Back to Blog
Computers

VS Code tasks.json for .NET Projects

A reusable task configuration for building, running, testing, and deploying ASP.NET projects with Tailwind CSS.

vscode dotnet tasks deployment tailwind
VS Code tasks.json for .NET Projects

Every time I start a new .NET project, I find myself hunting through old projects to copy the tasks.json configuration. This post documents the setup I use so I can find it in one place.

What tasks.json Does

VS Code's tasks.json file (in the .vscode folder) defines custom tasks that run from the Command Palette (Ctrl+Shift+P → "Run Task") or via keyboard shortcuts. For .NET projects, this typically means:

  • Building the solution
  • Running the project
  • Running tests
  • Publishing/deploying
  • Building CSS (for projects using Tailwind or similar)

The Full Configuration

Here's my current tasks.json for an ASP.NET MVC project with Tailwind CSS and Web Deploy publishing:

{
    "version": "2.0.0",
    "inputs": [
        {
            "id": "deployPassword",
            "type": "promptString",
            "description": "Enter deployment password",
            "password": true
        }
    ],
    "tasks": [
        {
            "label": "Build",
            "type": "process",
            "command": "dotnet",
            "args": [
                "build",
                "${workspaceFolder}/ProjectName.sln"
            ],
            "problemMatcher": "$msCompile",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "Run",
            "type": "shell",
            "command": "dotnet",
            "args": [
                "run",
                "--project",
                "${workspaceFolder}/ProjectName/ProjectName.csproj"
            ],
            "dependsOn": ["Build CSS"],
            "problemMatcher": "$msCompile",
            "presentation": {
                "reveal": "always",
                "panel": "dedicated"
            }
        },
        {
            "label": "Test",
            "type": "process",
            "command": "dotnet",
            "args": [
                "test",
                "${workspaceFolder}/ProjectName.sln"
            ],
            "problemMatcher": "$msCompile",
            "group": "test"
        },
        {
            "label": "Build CSS",
            "type": "shell",
            "command": "npm",
            "args": ["run", "build:css"],
            "options": {
                "cwd": "${workspaceFolder}/ProjectName"
            },
            "problemMatcher": []
        },
        {
            "label": "Watch CSS",
            "type": "shell",
            "command": "npm",
            "args": ["run", "watch:css"],
            "options": {
                "cwd": "${workspaceFolder}/ProjectName"
            },
            "isBackground": true,
            "problemMatcher": [],
            "presentation": {
                "reveal": "always",
                "panel": "dedicated"
            }
        },
        {
            "label": "Publish",
            "type": "shell",
            "command": "dotnet",
            "args": [
                "publish",
                "${workspaceFolder}/ProjectName/ProjectName.csproj",
                "-c",
                "Release",
                "-p:PublishProfile=ProfileName",
                "-p:Password=${input:deployPassword}"
            ],
            "dependsOn": ["Build CSS"],
            "problemMatcher": "$msCompile",
            "presentation": {
                "reveal": "always",
                "panel": "shared"
            },
            "group": "build"
        }
    ]
}

Key Concepts

Inputs for Secrets

The inputs array defines values prompted at runtime:

"inputs": [
    {
        "id": "deployPassword",
        "type": "promptString",
        "description": "Enter deployment password",
        "password": true
    }
]

Reference it in tasks with ${input:deployPassword}. The password: true flag masks input.

This keeps credentials out of the file while still enabling one-command deployment.

Task Dependencies

The dependsOn property chains tasks:

{
    "label": "Run",
    "dependsOn": ["Build CSS"],
    ...
}

The "Run" task automatically runs "Build CSS" first. This ensures Tailwind CSS is compiled before the app starts.

Problem Matchers

Problem matchers parse task output and populate VS Code's Problems panel:

"problemMatcher": "$msCompile"

The $msCompile matcher understands .NET compiler output, so build errors become clickable links to the source.

For tasks that don't produce parseable errors (like npm scripts), use an empty array:

"problemMatcher": []

Background Tasks

For long-running watchers:

{
    "label": "Watch CSS",
    "isBackground": true,
    "presentation": {
        "panel": "dedicated"
    }
}

The isBackground: true flag tells VS Code this task doesn't terminate, and panel: dedicated gives it its own terminal.

Task Groups

Groups organize tasks in the Command Palette:

"group": {
    "kind": "build",
    "isDefault": true
}

The default build task runs with Ctrl+Shift+B.

Working Directory

For tasks that need to run in a subdirectory:

"options": {
    "cwd": "${workspaceFolder}/ProjectName"
}

This is necessary when package.json lives in the project folder rather than the solution root.

Publishing with Web Deploy

The publish task uses a publish profile (.pubxml file in Properties/PublishProfiles/):

{
    "label": "Publish",
    "args": [
        "publish",
        "${workspaceFolder}/ProjectName/ProjectName.csproj",
        "-c",
        "Release",
        "-p:PublishProfile=ProfileName",
        "-p:Password=${input:deployPassword}"
    ],
    "dependsOn": ["Build CSS"]
}

The password is passed via -p:Password= because Web Deploy publish profiles don't store passwords.

Publish Profile Setup

The .pubxml file in Properties/PublishProfiles/ contains:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  <PropertyGroup>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <PublishProvider>AzureWebSite</PublishProvider>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish>https://yoursite.com/</SiteUrlToLaunchAfterPublish>
    <LaunchSiteAfterPublish>false</LaunchSiteAfterPublish>
    <MSDeployServiceURL>yourhost.com</MSDeployServiceURL>
    <DeployIisAppPath>yoursite.com</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>false</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
    <EnableMSDeployBackup>true</EnableMSDeployBackup>
    <UserName>deployuser</UserName>
  </PropertyGroup>
</Project>

Running Tasks

  • Command Palette: Ctrl+Shift+P → "Tasks: Run Task" → select task
  • Default Build: Ctrl+Shift+B runs the default build task
  • Terminal Menu: Terminal → Run Task

Keyboard Shortcuts

For frequently-used tasks, add keybindings in keybindings.json:

{
    "key": "ctrl+shift+r",
    "command": "workbench.action.tasks.runTask",
    "args": "Run"
}

Adapting for Your Project

To use this configuration:

  1. Copy .vscode/tasks.json to your project
  2. Replace ProjectName with your actual project/solution names
  3. Replace ProfileName with your publish profile name
  4. Adjust paths if your structure differs
  5. Remove CSS tasks if not using Tailwind/npm

The file is version-controlled, so team members get the same task definitions.

Comments

More in Computers

Adding New Domains to Your Certbot + Cloudflare Setup
Computers

Adding New Domains to Your Certbot + Cloudflare Setup

You set up SSL automation once and it worked great. Then you added a new domain and hit every gotcha you'd forgotten about. Here's the checklist.

ssl letsencrypt certbot cloudflare raspberry-pi troubleshooting
SEO Demystified: How to Stop Being Invisible to Google
Computers

SEO Demystified: How to Stop Being Invisible to Google

You built a beautiful site but Google can't find it. Here's what actually matters for SEO—meta tags, structured data, sitemaps—explained for developers who'd rather write code than read marketing blogs.

seo meta-tags open-graph json-ld sitemap aspnet-core