Welcome to Shaun Luttin's public notebook. It contains rough, practical notes. The guiding idea is that, despite what marketing tells us, there are no experts at anything. Sharing our half-baked ideas helps everyone. We're all just muddling thru. Find out more about our work at bigfont.ca.

Debug with a specific .NET 5 runtime in Visual Studio

Tags: asp.net-5, asp.net, visual-studio, visual-studio-2015

Three cascading locations

Sometimes we want to debug a project in Visual Studio using a specific runtime version, platform, and architecture. In those cases, it’s useful to know that the Visual Studio debug runtime configuration cascades. That is, project settings override solution settings, and solution settings override the default dnvm one. We can configure the runtime in three different places: the project, the solution, or the dnvm.

First, some definitions & synonyms

  • Runtime Version. Versions include 1.0.0-beta4, the recent 1.0.0-beta5, and the prerelease 1.0.0-beta6. The latter also includes specific build numbers such as 1.0.0-beta6-12170.
  • Runtime Platform. The platform is also known as the “runtime type” or just as the “runtime.” Platforms include the .NET Framework (clr) and .NET Core (coreclr). When we’re in the dnvm command line, clr means the .NET Framework and coreclr means .NET Core.
  • Runtime Architecture. There are two: x86 and x64.

Project Specific Runtime

Property Pages > Debug > Use Specific Runtime

  1. This is project specific.
  2. It overrides the SDK version that we set in global.json.
  3. We can set the runtime version, platform (aka type), and architecture here.
  4. The available runtime options are the same as what we see with dnvm list from the command line.
  5. If we don’t check “Use Specific Runtime,” then Visual Studio reverts the version to .NET Framework and the architecture to x86.

Visual Studio persists changes to the project specific runtime within the src/MyProject/Properties/launchSettings.json file.

Solution Wide Runtime

global.json > sdk > version

  1. This is a solution wide place to set the runtime.
  2. It overrides the runtime listed at dnvn alias default.
  3. We can set the version here (e.g. 1.0.0-beta5) but not the type nor the architecture.
  4. If we want to set a solution wide type and architecture, then we can use dnvm to create a new alias, and then reference that alias within global.json.
  5. If we don’t specific a runtime in global.json, then Visual Studio will use the default alias.

DNVM Default Runtime

dnvm alias default

  1. This the last place Visual Studio checks for what runtime to use.
  2. It’s relevant only if we haven’t configured the runtime in either a projects debug property pages nor a solutions global.json file.

If none of the above are set, Visual Studio will not run the project. Rather, it will complain that we need to install a DNX.

Some other notes on setting the runtime

  1. Visual Studio debug doesn’t care about dnvm use nor what dnvm list says is the active runtime.
  2. To see changes in our runtime configuration, we need to restart the app. E.g. we need to “start without debugging.” Simply refreshing the page won’t do.
  3. Do not “cross the streams.” That is, if our configured debug runtime is beta5, then our project.json dependencies must also be set to beta5.
  4. While I’ve succeeded in using beta4, beta5, and beta6 versions and using both clr and coreclr, I have not been able to use the x64 architecture. Whenever I set it in the Project Properties > Debug panel, the RuntimeEnvironment still says x86.

Inspecting the actual runtime of the app

We can add the following to Startup.Configure to inspect the version, platform, and architecture that our app is using in real time.

public void Configure(IApplicationBuilder app, IRuntimeEnvironment runtimeEnv)
{
    app.Run(async (context) =>
    {
        var version = runtimeEnv.RuntimeVersion.ToString();
        var platform = runtimeEnv.RuntimeType.ToString();
        var architecture = runtimeEnv.RuntimeArchitecture.ToString();
        var builder = new StringBuilder();
        builder.Append("<h1>Specific DNX Version</h1>");
        builder.AppendFormat("<p>Version:  {0}</p>", version);
        builder.AppendFormat("<p>Platform: {0}</p>", platform);
        builder.AppendFormat("<p>Architecture:  {0}</p>", architecture);
        await context.Response.WriteAsync(builder.ToString());
    });
}