2

I have a server that currently hosts many .net core v2 services in IIS.

I had a to make a new service. Normally I would just use whatever runtime the server has installed, but I thought, ".Net Core can deploy self contained applications, so I can have v2 services side by side with v3 ones."

I am worried I was wrong.

When I run my self contained application, it gives the following error:

Handler "aspNetCore" has a bad module "AspNetCoreModuleV2" in its module list.

When I look this up I find, that I will need to install the hosting bundle. Which when you go to the .net core site that has it, it shows as the recommended install method for .Net Core (on IIS Machines).

This is where I am starting to get worried. I thought I did not have to install .net core 3 on my server. I thought I could run a self contained application.

I can't install .Net Core v3 without testing that all the existing services that target .Net Core v2 work fine on the .Net Core v3 runtime.

So, it is looking like I will have to go downgrade my service to v2 (yuck, I hate working to go backwards.)

But before I do it, I thought I would ask:
Is there anyway to host an Asp.Net Core v3 Web API service on IIS that only has the .Net Core v2 runtime on it?

Vaccano
  • 78,325
  • 149
  • 468
  • 850
  • Self-contained deployment works everywhere except on IIS. So in your case you have no other option but to install the necessary version of ASP.NET Core module on IIS (.NET Core runtime is not needed as your self-contained binaries already have the runtime). BTW, NET Core 2.1's ASP.NET Core module won't work with ASP.NET Core 3.1 web apps, and that's why you got the module error. – Lex Li Feb 22 '20 at 01:34
  • Would you consider IIS to act as reverse proxy/URL rewrite front-end for that? – timur Feb 24 '20 at 10:20
  • this is where containerization comes to the rescue – Jonathan Busuttil Feb 24 '20 at 10:55

1 Answers1

3

Which runtime version to use is defined by your project file, so different runtimes can run in same machine without any issue. Let's say, for instance you have two services: Service1 is built using .net core 2.1 and Service2 is build with .net core 3.1. The project files will look like this:

Service1.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

Service2.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

Once you run your application via dotnet run or dotnet ServiceX.dll, the dotnet executable is the host of the application, and selects the correct runtime based on the assembly metadata. The runtime to use is actually written in the compiled DLL.

Therefore, 2.* and 3.* application can totally coexist in the same machine, provided the required runtimes are installed.

Read more here: https://learn.microsoft.com/en-us/dotnet/core/versions/selection

Check this experiment out. On my machine have the following installed: 1) Asp.Net Core Runtime 2.1.14 2) Asp.Net Core Runtime 3.1.2 3) IIS 10.0 4) Asp.Net Core Module (installed with hosting bundle)

I created 2 applications, one for each runtime:

dotnet new web -f netcoreapp2.1 -o Service1

and

dotnet new web -f netcoreapp3.1 -o Service2

I then modified both application Startup.cs like this:

    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                var framework = Assembly
                    .GetEntryAssembly()?
                    .GetCustomAttribute<TargetFrameworkAttribute>()?
                    .FrameworkName;
                var taskLocation = typeof(Task).Assembly.Location;
                await context.Response.WriteAsync($@"Hello World from {framework}
Location of Task assembly: {taskLocation}.
                ");
            });
        }
    }

I published both services in release: Service1: C:\Users\info\source\repos\Service1> dotnet publish -c Release Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Core Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 159,32 ms for C:\Users\info\source\repos\Service1\Service1.csproj.
  Service1 -> C:\Users\info\source\repos\Service1\bin\Release\netcoreapp2.1\Service1.dll
  Service1 -> C:\Users\info\source\repos\Service1\bin\Release\netcoreapp2.1\publish\

Service2:

C:\Users\info\source\repos\Service2> dotnet publish -c Release
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 41,98 ms for C:\Users\info\source\repos\Service2\Service2.csproj.
  Service2 -> C:\Users\info\source\repos\Service2\bin\Release\netcoreapp3.1\Service2.dll
  Service2 -> C:\Users\info\source\repos\Service2\bin\Release\netcoreapp3.1\publish\

Under IIS I created two website, one for each service, each pointing at the right output directory

service1.lvh.me >>> C:\Users\info\source\repos\Service1\bin\Release\netcoreapp2.1\publish\

service2.lvh.me >>> C:\Users\info\source\repos\Service2\bin\Release\netcoreapp3.1\publish\

I then visited each website. Visiting service1.lvh.me I got: enter image description here and visiting service2.lvh.me I got: enter image description here

As you can see each application is requiring the correct version of the framework, and framework types are loaded from specific folders.

There is therefore no problem to have different versions of .net core framework running on the same machine, and web applications running over specific version on the same IIS.

Claudio Valerio
  • 2,302
  • 14
  • 24
  • Do you know of any docs where this applies to IIS? (I am not using `dotnet run`). I would love to see a doc on ”IIS side by side support”. (I am mistrustful of the general doc’s info on side by side because it also speaks of “self contained” apps with no caveats for IIS, and it does not work for IIS.) – Vaccano Feb 24 '20 at 15:05
  • You are not using "dotnet run", but you are probably running through AspNetCoreModule, that starts your application by starting "dotnet MyApp.dll". The runtime selection is exactly the same, as explained in https://docs.microsoft.com/en-us/dotnet/core/versions/selection#framework-dependent-apps-roll-forward: "When you run an application from source with dotnet run, from a framework-dependent deployment with dotnet myapp.dll, or from a framework-dependent executable with myapp.exe, the dotnet executable is the host for the application." I've added an example to my answer that I hope can help. – Claudio Valerio Feb 24 '20 at 16:44
  • This looks promising. .Net Core 3 apparently needs AspNetCoreModuleV2 to run inIIS. That is fine. My worry is that it also changes some files that are used by .Net Core 2 IIS when it installs. Is there a way to see what IIS files are being used by Service 1 and Service 2 in your example? – Vaccano Feb 24 '20 at 17:49
  • I'm not aware of any IIS component that could be used by .net core, unless your application is some sort of IIS Management app (and in that case it would communicate with IIS through some sort of service, instead of tampering with it directly). IIS load your .net core application in a contained space (application pool) and isolates it from other applications. Just think about all the companies serving shared spaces for websites: they couldn't do that if framework versioning would be an issue for older applications. – Claudio Valerio Feb 24 '20 at 18:37
  • IMHO you are worring for nothing, but if you are still unconvinced, try get a virtual machine up with the same config of your server, install your older apps, your new one, and check that everything is ok. – Claudio Valerio Feb 24 '20 at 18:38