为了运行ASP.NET Core应用程序,你需要使用WebHostBuilder来配置和启动一个宿主。

什么是宿主?

ASP.NET Core应用程序需要在宿主中执行,一个宿主必须实现IWebHost接口,该接口暴露了功能和服务的集合,以及一个Start方法。宿主通常使用WebHostBuilder的实例来创建,该实例构建并返回一个WebHost实例。WebHost引用一个将用于处理请求的服务器。

宿主和服务器有什么不同?

宿主负责应用程序启动和生命周期的管理。服务器负责接受HTTP请求。宿主的部分职责还包括确保应用程序服务和服务器可用并正确配置。你可以把宿主看作是服务器的包装。宿主被配置为使用一个特定的服务器;服务器并不知道它的宿主。

设置宿主

使用WebHostBuilder实例来创建一个宿主。这通常在你应用的入口点进行设置:public static void Main(在项目模板的Program.cs中)。下面的代码将演示如何使用WebHostBuilder来构建一个宿主。

public class Program
{
    public static void Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .AddCommandLine(args)
            .AddEnvironmentVariables(prefix: "ASPNETCORE_")
            .Build();

        var host = new WebHostBuilder()
            .UseConfiguration(config)
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

WebHostBuilder负责创建宿主,宿主会为当前应用程序启动服务器。WebHostBuilder需要你提供一个实现了IServer(上面代码中的UseKestrel)接口的服务器。UseKestrel指定应用程序会使用Kestrel服务器。

服务哭器的Content Root(内容根)决定它将在哪里搜索内容文件,比如MVC视图文件。默认的内容根是应用程序运行的文件夹。

如果应用程序需要使用IIS,需要在构建宿主时调用UseIISIntegration方法。注意这不像UseKestrel所做的,这不会去配置服务器,为了让ASP.NET Core使用IIS,你必须相同指定UseKestrelUseIISIntegration。Kestrel被设计为在代理后运行,而不应该直接面向Internet部署。UseIISIntegration指定IIS为反向代理服务器。

注:UseKestrelUseIISIntegration是两个完全不同的操作。IIS只是作为一个反向代理。UseKestrel创建Web服务器和托管代码。UseIISIntegration指定IIS作为反向代理服务器。它同时会检查IIS/IISExpress使用的环境变量,并做出比如使用哪个动态端口,设置什么Header等决定。然而,它不处理或创建IServer

配置一个宿主(以及一个ASP.NET Core应用程序)的最小实现仅仅包含一个服务器和应用程序请求管道的配置:

var host = new WebHostBuilder()
    .UseKestrel()
    .Configure(app =>
    {
        app.Run(async (context) => await context.Response.WriteAsync("Hi!"));
    })
    .Build();

host.Run();

注:当设置一个宿主,你可以提供ConfigureConfigureServices方法,而不是或者除了指定Startup类(它也必须定义这些方法)。多次调用ConfigureServices会追加配置;调用Configure 或者 UseStartup会替换之前的设置。

配置宿主

WebHostBuilder提供了方法用于为宿主设置大多数可用的配置,它也可以通过UseSetting和相关的键直接设置。比如,指定应用程序的名字:

new WebHostBuilder()
    .UseSetting("applicationName", "MyApp")

宿主配置值

Application Name string

键:applicationName。这个配置设置指定的值将从IHostingEnvironment.ApplicationName返回。

Capture Startup Errors bool

键:captureStartupErrors。默认是false。当值为false时,在启动过程中的错误会导致宿主退出。当值为true时,宿主会捕捉Startup类中的任何异常,并试图启动服务器。将会为每个请求显示错误页面(一般的,或详细的,这取决于下面提到的详细错误设置)。通过CaptureStartupErrors方法来设置。

new WebHostBuilder()
    .CaptureStartupErrors(true)

Content Root string

键:contentRoot。默认是应用程序集所在的文件夹(针对Kestrel;IIS将默认使用Web项目根目录)。这个设置决定了ASP.NET Core将从哪里开始搜索内容文件,比如MVC视图。内容根同时被作为Web根设置的基础路径使用。通过UseContentRoot方法来进行设置。路径必须是存在的,否则宿主会启动失败。

new WebHostBuilder()
    .UseContentRoot(Directory.GetCurrentDirectory())

Detailed Errors bool

键:detailedErrors。默认是false。当值为true时(或者环境设置为”Development”时),应用程序将会显示详细的启动错误信息,而不是一般的错误页面。通过UseSetting进行设置。

new WebHostBuilder()
    .UseSetting("detailedErrors", "true")

当详细错误设置为false并且捕捉启动错误是true时,每一个请求服务器的响应中会显示一般的错误页面。

当详细错误设置为true并且捕捉启动错误是true时,每一个请求服务的响应中会显示一个详细的错误页面。

Environment string

键:detailedErrors。默认为”Production”。可以设置为任何值。框架预定义的值包含”Development”, “Staging”, 和 “Production”。值不区分大小写。通过UseEnvironment方法进行设置。

new WebHostBuilder()
    .UseEnvironment("Development")

注:默认情况下,环境是从ASPNETCORE_ENVIRONMENT环境变量中读取。

Server URLs string

键:detailedErrors。使用分号(;)来分隔服务器应该响应的URL前缀列表。例如,http://localhost:123。域名可以使用”*“替换,表明服务器需要对任何指定端口和协议的IP地址或者域名进行请求的监听(比如,http://*:5000 or https://*:5001)。协议(http:// 或者 https://)必须包含在每个URL里面。前缀由配置好的服务器解释;服务器之间支持的格式会有所不同。

new WebHostBuilder()
    .UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")

Startup Assembly string

键: startupAssembly。决定搜索Startup类的程序集。通过UseStartup方法进行设置。可以使用WebHostBuilder.UseStartup<StartupType>引用特定类型。如果调用多次UseStartup方法,最后一个调用会生效。

new WebHostBuilder()
    .UseStartup("StartupAssemblyName")

Web Root string

键: webroot。如果不指定,默认是(Content Root Path)\wwwroot。通过UseWebRoot进行设置。

new WebHostBuilder()
    .UseWebRoot("public")

使用Configuration来设置宿主所需的配置值。这些值可能随后被重写。这可以使用UseConfiguration 指定。

public static void Main(string[] args)
{
    var config = new ConfigurationBuilder()
    .AddCommandLine(args)
    .AddJsonFile("hosting.json", optional: true)
    .Build();

    var host = new WebHostBuilder()
    .UseConfiguration(config)
    .UseKestrel()
    .Configure(app =>
    {
        app.Run(async (context) => await context.Response.WriteAsync("Hi!"));
    })
    .Build();

    host.Run();
}

在上面的例子中,可能通过传递命令行参数来配置宿主,或者在hosting.json文件中进行配置。要指定在特定的URL上运行宿主,你可以从命令行传递所需要的值:

dotnet run --urls "http://*:5000"

Run方法启动Web应用程序并阻止调用线程直到宿主关闭。

host.Run();

你可以通过调用宿主的Start方法来以非阻塞的方式运行宿主。

using (host)
{
    host.Start();
    Console.ReadLine();
}

传送一个URL列表到Start方法,它将监听指定的URL:

var urls = new List<string>() {
    "http://*:5000",
    "http://localhost:5001"
    };
var host = new WebHostBuilder()
    .UseKestrel()
    .UseStartup<Startup>()
    .Start(urls.ToArray());

using (host)
{
    Console.ReadLine();
}

原文链接

Hosting

个人博客

我的个人博客