Notes from changing AspNet Core 2.1-preview1 app to IIS In-Process hosting

The AspNet Core 2.1-preview1 is out and it brings a ton of interesting improvements. One of which is that now you are able to host your AspNet app inside the IIS process. This, according to AspNet team will increase the request throughput by around 4.4 times. I did it for my app and faced a few issues that I though is worth describing here along with a process that I followed. “Improvements to IIS hosting” blog post from AspNet team lists steps needed to change your app hosting model. To my surprise there is only three of them:

  1. Install Windows Server Hosting bundle
  2. Install AspNet Core Module (ANCM) module for IIS
  3. Set AspNetCoreModuleHostingModel to inprocess in your project file.

Installation of Windows Server Hosting bundle is pretty straight forward and quite fast, I didn’t encounter any issues with it. One note here is that it is recommended to do iisreset after this step.

For the installation of ANCM there is a PowerShell script written by @shirhatti that you can get from the GitHub repository. Here is how you execute the script:

      Invoke-WebRequest -Uri https://raw.githubusercontent.com/shirhatti/ANCM-ARMTemplate/master/install-ancm.ps1 -OutFile install-ancm.ps1
      .\install-ancm.ps1
    

UPD: The PR with a fix for the script was merged, so I updated the URL to take the version of the script from official repository.

If the script executed successfully there should be an AspNet Core Module in the list of modules in IIS.

ANCM

Since this is a Native module the app pool can stay with “No managed code” option for CLR version.

Now lets get to what needs to change in the application code itself. First thing is to set AspNetCoreModuleHostingModel to inprocess in the project file. This is done by adding a PropertyGroup to the project file:

      <PropertyGroup>
        <AspNetCoreModuleHostingModel>inprocess</AspNetCoreModuleHostingModel>
      </PropertyGroup>
    

This will not change the behavior of the app when running locally, but it will instruct MSBuild to add hostingModel="inprocess" property to the ANCM entry in the web.config. The resulting web.config should look like this:

      <?xml version="1.0" encoding="utf-8"?>
      <configuration>
        <system.webServer>
          <handlers>
            <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
          </handlers>
          <aspNetCore processPath="dotnet" arguments=".\InProcTest.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
        </system.webServer>
      </configuration>
    

If you’ve created your application from 2.0 template, as I did, you will have UseContentRoot(Directory.GetCurrentDirectory()) entry in Program.cs. This should be removed as it will cause the application to fail. The reason is that when hosting inside w3wp GetCurrentDirectory will return C:\windows\system32\inetsrv while the app is in the C:\inetpub\wwwroot\InProcTest so ANCM will not find your app and will complain with the status code of 500. The 2.1 app is smart enough to figure out its own location anyway. :)

UPD: Before, I mentioned that UseIISIntegration() can be removed from the Program.cs as it was not needed, this is not entirely correct. @jkotalik pointed out that UseIISIntegration() is still necessary for InProcess hosting as it will register IIS specific services and options and will set the content root path correctly. The good news it that WebHost.CreateDefaultBuilder will add UseIISIntegration() by default, so no need to add it in Program.cs.

After this changes, run the app and it should load without issues.

Side note, with this model, you can run only one app per IIS process. This is a decision that AspNet team made and also currently a limitation from .Net Core as it does not have support for multiple AppDomains.

Happy hosting!