hckr.fyi // thoughts

Debugging .NET Framework Web Applications in Visual Studio Code

by Michael Szul on

Visual Studio Code is one of the best editors--and one could argue IDEs--on the market. It's lightweight. It's highly extensible. It's command-oriented. It has great task management functionality. It works great when debugging applications.

But Visual Studio Code is centered on Microsoft's cross-platform policy. As a result, it's main focus when it comes to C# and web applications (ASP.NET MVC/Web API) is with .NET Core. The C# debugger is handled by OmniSharp, which is a cross-platform project with a storied history of supporting C# on Linux via Mono. The focus on .NET Core meant that if you were a .NET Framework developer (or had legacy applications), and you wanted to switch to Visual Studio Code as your permanent IDE, you couldn't because you would lose out on debugging.

Changes over the last year or so have made .NET Framework debugging more palatable, but documentation is still sparse.

Debugging .NET Framework applications--such as ASP.NET MVC web applications--requires you to make some adjustments to your project and to your Visual Studio Code settings. In your *.csproj file, find the <DebugType> node, and set it to "portable" for the configurations you are working with:

<DebugType>portable</DebugType>
    

There will be a <DebugType> node for each of your configuration types. I tend to only modify the one for the configuration that I am debugging--usually where the configuration equals… debug. Go figure.

With Visual Studio Code, when you add a debug task, the launch.json configuration will have a "type" of "coreclr" to specify what the debug configuration is. We're going to want to make sure of two things: We need the type to reflect the .NET Framework instead of .NET Core, and we want an attach configuration instead of a launch. My configuration looks like this:

{
           "name": "iis express",
           "type": "clr",
           "request": "attach",
           "processName": "iisexpress"
    }
    

The "name" here isn't important. It's just what shows up in the dropdown when selecting a debug configuration. The "type" is "clr" instead of "coreclr" because we need to use the .NET Framework. This will only work if the DLL that is compiled has a "portable" debug type, which is why we made the CSPROJ change earlier. The "request" is "attach" because we are going to attach to an existing IIS Express process. I have a "processName" set to "iisexpress" since we are running our application with IIS Express.

You have two choices when it comes to running the web application. You can either manually edit your applicationhost.config file for IIS Express, or can use the IIS Express Visual Studio Code extension. You can usually find this in the IIS Express folder in your Documents for your user folder. For example, mine is found in C:\Users\micha\Documents\IISExpress\config. The caveat here is that if you also use ReSharper or Visual Studio proper for working on your project, there may be an IIS Express configuration local to the project that you have to edit as well. For example, there might be a .vs folder with IIS Express configuration information in it. You'll have to add a <site> node entry in here for your application, and then you can launch the instance via: iisexpress /site:YOUR_SITE_NAME.

My preference, however, is to use the IIS Express Visual Studio Code extension. If you use this. You simply Ctrl + Shift + p to bring up the command palette, and then type IIS. You should see the command for starting IIS Express in the current folder. Click on it to launch your web application.

Once you've launched your IIS Express instance for the web application you want to debug, you can then click the debug launch button and select the "iis express" configuration to attach the debugger to your process.

You should be all set to debug.

Many thanks to Andrew J Richardson who helped me work through this process. It turns out that it works quite well with an "attach" process, but not a "launch" one for debugging.