IIS application initialization - setup

With IIS 8.0 Microsoft has introduced a new feature called Application Initialization. Application Initialization allows you to pre load some initialization tasks for your application before the application pool will handle user requests. For example: you could initialize a cache with some static types, objects or files used by your application logic. From the official MSDN Documentation

The IIS 8.0 Application Initialization feature enables website administrators to configure IIS 8.0 to proactively perform initialization tasks for one or more web applications. While an application is being initialized, IIS 8.0 can also be configured to return static content as a placeholder or “splash page” until an application has completed its initialization tasks.

Before you can use Application Initialization Feature you must ensure, the appropriate IIS Module is installed on your web server. This can be done either by using the Server Manager or Powershell. In an elevated PowerShell prompt run the following command:

Enable-WindowsOptionalFeature -Online -FeatureName IIS-ApplicationInit

Application Initialization Module

Tip: Use my IIS feature installation script for a complete setup of an IIS Server on Windows Server 2016/2019 and Windows 10.

ASP.NET Core Demo

Let’s start with a simple ASP.NET Core Api controller which acts as an entry point for the initialization. The idea behind this endpoint is to provide an API which will be called by the IIS Application Initialization Module to do some initialization tasks like data loading, caching etc. before the web sites handles user requests.

[ApiController]
public class InitController : ControllerBase
{
    private readonly ILogger<InitController> _logger;
    public InitController(ILogger<InitController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    [Route("api/init/start")]
    public IActionResult AppInit()
    {
        _logger.LogInformation("app initializer");
        return Ok();
    }
}

Since Application Initialization is an IIS feature, of course a web.config file is required to perform all necessary configurations. Note: /api/init/start points to my api controller route

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true">
        <add initializationPage="/api/init/start" />
      </applicationInitialization>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\dotnet-iis-preload.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

Copy and Paste this web.config file into your Web-Project root directory and set Copy to Output Directory to always either in Visual Studio or directly inside csproj.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Content Update="web.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
</Project>

In the configuration file shown above, i have set the property stdoutLogEnabled to true, so that the correct functionality can be checked by using the built-in logging capabilities. In productive environments, this property should always be set to false. See Log creation and redirection for further details.

Now, you’re ready to publish your web app using dotnet publish command

dotnet publish -o d:\temp\preload

Create a new IIS-Site and set the physical path to d:\temp\preload. For ASP.NET Core applications, the application pool must be set to No Managed Code.

On your site under “Advanced Settings” you must set Preload Enabled to true. With this setting, IIS sends a “fake request” to the application every time it restarts or the associated application pool starts up.

Application Initialization Module

As soon your application pool has been started, you should see your app initializers log entries under .\logs\stdout

info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: D:\temp\preload
info: dotnet_iis_preload.Controllers.InitController[0]
      app initializer

this happens everytime your appliction pool has been started or the pool has been recycled.

The Application Initialization feature usually works quite well, but problems can occur depending on the configuration of your Web Site. In order for the feature to work properly, a few conditions must be met. See my blog post IIS application initialization - troubleshooting where I point out the possible problems and explain how to analyze and fix them.