Servers

By Steve Smith and Stephen Halter

ASP.NET Core is completely decoupled from the web server environment that hosts the application. ASP.NET Core supports hosting in IIS and IIS Express, and self-hosting scenarios using the Kestrel and WebListener HTTP servers. Additionally, developers and third party software vendors can create custom servers to host their ASP.NET Core apps.

View or download sample code

Servers and WebHostBuilderExtensions

ASP.NET Core was designed to decouple web applications from the underlying HTTP server. Traditionally, ASP.NET apps have been windows-only hosted on Internet Information Server (IIS). The recommended way to run ASP.NET Core applications on Windows is still using IIS, but as a reverse-proxy server. The ASP.NET Core Module in IIS manages and proxies requests to the Kestrel HTTP server hosted out-of-process. ASP.NET Core ships with two different HTTP servers:

  • Microsoft.AspNetCore.Server.Kestrel (AKA Kestrel, cross-platform)
  • Microsoft.AspNetCore.Server.WebListener (AKA WebListener, Windows-only, preview)

ASP.NET Core does not directly listen for requests, but instead relies on the HTTP server implementation to surface the request to the application as a set of feature interfaces composed into an HttpContext. While WebListener is Windows-only, Kestrel is designed to run cross-platform. You can configure your application to be hosted by any of these servers via extension methods on WebHostBuilder.

The default web host for ASP.NET apps developed using Visual Studio is IIS Express functioning as a reverse proxy server for Kestrel. The “Microsoft.AspNetCore.Server.Kestrel” and “Microsoft.AspNetCore.Server.IISIntegration” dependencies are included in project.json by default, even with the Empty web site template. Visual Studio provides support for multiple profiles. In addition to the default profile for running in IIS Express, the templates include a second profile that executes the app directly relying on Kestrel for self-hosting. You can manage these profiles and their settings in the Debug tab of your web application project’s Properties menu or from the launchSettings.json file.

../_images/serverdemo-properties.png

Note

The ASP.NET Core Module for IIS supports proxying requests to Kestrel but not WebListener.

The sample project’s project.json file includes the dependencies and tools required to support each server:

project.json (truncated)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "version": "1.0.0-*",

  "dependencies": {
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.AspNetCore.Server.WebListener": "0.1.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.CommandLine": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

UseKestrel and UseWebListener both have an overload taking an options configuration callback that can be used for server-specific configuration. For instance, WebListener exposes AuthenticationManager that can be used to configure the server’s authentication. Configuration can easily be driven by JSON text files, environment variables, command line arguments and more with the help of ASP.NET Core’s Configuration facilities.

Kestrel is selected by default in the sample project in the Program.Main method which is the entry point for the application. The sample is programmed so WebListener can be selected instead by passing --server WebListener as a command line argument. The sample explicitly reads the --server command line argument to determine whether to call UseKestrel or UseWebListener. The --server command line flag is not interpreted by the ASP.NET Core framework to have any special meaning.

Note

builder.UseUrls("http://localhost") configures Kestrel and WebListener to only listen to local requests. Replace “localhost” with “*” to also listen to external requests.

Program.cs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public static int Main(string[] args)
{
    // Add command line configuration source to read command line parameters.
    var config = new ConfigurationBuilder()
        .AddCommandLine(args)
        .Build();

    Server = config["server"] ?? "Kestrel";

    var builder = new WebHostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseConfiguration(config)
        .UseStartup<Startup>();

    // The default listening address is http://localhost:5000 if none is specified.
    // Replace "localhost" with "*" to listen to external requests.
    // You can use the --urls flag to change the listening address. Ex:
    // > dotnet run --urls http://*:8080;http://*:8081

    // Uncomment the following to configure URLs programmatically.
    // Since this is after UseConfiguraiton(config), this will clobber command line configuration.
    //builder.UseUrls("http://*:8080", "http://*:8081");

    // If this app isn't hosted by IIS, UseIISIntegration() no-ops.
    // It isn't possible to both listen to requests directly and from IIS using the same WebHost,
    // since this will clobber your UseUrls() configuration when hosted by IIS.
    // If UseIISIntegration() is called before UseUrls(), IIS hosting will fail.
    builder.UseIISIntegration();

    if (string.Equals(Server, "Kestrel", StringComparison.OrdinalIgnoreCase))
    {
        Console.WriteLine("Running demo with Kestrel.");

        builder.UseKestrel(options =>
        {
            if (config["threadCount"] != null)
            {
                options.ThreadCount = int.Parse(config["threadCount"]);
            }
        });
    }
    else if (string.Equals(Server, "WebListener", StringComparison.OrdinalIgnoreCase))
    {
        Console.WriteLine("Running demo with WebListener.");

        builder.UseWebListener(options =>
        {
            // AllowAnonymous is the default WebListner configuration
            options.Listener.AuthenticationManager.AuthenticationSchemes =
                AuthenticationSchemes.AllowAnonymous;
        });
    }

Supported Features by Server

ASP.NET defines a number of Request Features. The following table lists the WebListener and Kestrel support for request features.

Feature WebListener Kestrel
IHttpRequestFeature Yes Yes
IHttpResponseFeature Yes Yes
IHttpAuthenticationFeature Yes No
IHttpUpgradeFeature Yes (with limits) Yes
IHttpBufferingFeature Yes No
IHttpConnectionFeature Yes Yes
IHttpRequestLifetimeFeature Yes Yes
IHttpSendFileFeature Yes No
IHttpWebSocketFeature No* No*
IHttpRequestIdentifierFeature Yes No
ITlsConnectionFeature Yes Yes
ITlsTokenBindingFeature Yes No

ServerFeatures Collection

The IApplicationBuilder available in the Startup‘s Configure method exposes the ServerFeatures property of type IFeatureCollection. Kestrel and WebListener both expose only a single feature, IServerAddressesFeature, but different server implementations may expose additional functionality.

Port 0 binding with Kestrel

Kestrel supports dynamically binding to an unspecified, available port by specifying port number 0 in UseUrls, e.g. builder.UseUrls("http://127.0.0.1:0"). The IServerAddressesFeature can be used to determine which available port Kestrel actually bound to.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));

    var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>();

    app.UseStaticFiles();

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync($"Hosted by {Program.Server}\r\n\r\n");

        if (serverAddressesFeature != null)
        {
            await context.Response.WriteAsync($"Listening on the following addresses: {string.Join(", ", serverAddressesFeature.Addresses)}\r\n");
        }

        await context.Response.WriteAsync($"Request URL: {context.Request.GetDisplayUrl()}");
    });
}

Note

Binding to http://localhost:0 is not supported. You must either bind to http://127.0.0.1:0, http://[::1]:0 or both individually.

IIS and IIS Express

IIS is the most feature rich server, and includes IIS management functionality and access to other IIS modules. Hosting ASP.NET Core no longer uses the System.Web infrastructure used by prior versions of ASP.NET.

IIS Express can be launched by Visual Studio using the default profile defined by the ASP.NET Core templates. Publishing and Deployment provides guidelines for publishing to IIS.

ASP.NET Core Module

In ASP.NET Core on Windows, the web application is hosted by an external process outside of IIS. The ASP.NET Core Module is an IIS 7.5+ module which is responsible for process management of HTTP listeners and used to proxy requests to the processes that it manages.

Kestrel

Kestrel is a cross-platform web server based on libuv, a cross-platform asynchronous I/O library. You add support for Kestrel by including Microsoft.AspNetCore.Server.Kestrel in your project’s dependencies listed in project.json and calling UseKestrel.

Learn more about working with Kestrel to create Your First ASP.NET Core Application on a Mac Using Visual Studio Code.

WebListener

WebListener is a Windows-only HTTP server for ASP.NET Core. It runs directly on the Http.Sys kernel driver, and has very little overhead. WebListener cannot be used with the ASP.NET Core Module for IIS. It can only be used independently.

You can add support for WebListener to your ASP.NET application by adding the Microsoft.AspNetCore.Server.WebListener dependency in project.json and calling UseWebListener

Note

Kestrel is designed to be run behind a proxy (for example IIS or Nginx) and should not be deployed directly facing the Internet.

Choosing a server

If you intend to deploy your application on a Windows server, you should run IIS as a reverse proxy server that manages and proxies requests to Kestrel. If deploying on Linux, you should run a comparable reverse proxy server such as Apache or Nginx to proxy requests to Kestrel (see Publish to a Linux Production Environment).

Custom Servers

You can create your own server in which to host ASP.NET apps, or use other open source servers. When implementing your own server, you’re free to implement just the feature interfaces your application needs, though at a minimum you must support IHttpRequestFeature and IHttpResponseFeature.

Since Kestrel is open source, it makes an excellent starting point if you need to implement your own custom server. Like all of ASP.NET Core, you’re welcome to contribute any improvements you make back to the project.

Kestrel currently supports a limited number of feature interfaces, but additional features will be added in the future.

The Using ASP.NET Hosting on an OWIN-based server guide demonstrates how to write a Nowin based IServer.