原文:Hosting
作者:Steve Smith
翻譯:婁宇(Lyrics)
校對:何鎮汐、許登洋(Seay)
為了運行 ASP.NET Core 應用程序,你需要使用 WebHostBuilder 配置和啟動一個宿主.
什么是宿主?
ASP.NET Core 應用程序需要在宿主中執行。宿主必須實現 IWebHost 接口,這個接口暴露了功能和服務的集合,以及 Start
方法。宿主通常使用 WebHostBuilder 的實例進行創建,該實例構建並返回一個 WebHost 實例。WebHost
引用服務器來處理請求。學習更多關於 服務器。
宿主和服務器的不同之處是什么?
宿主負責應用程序啟動和生命周期管理。服務器負責接受 HTTP 請求。確保應用程序服務和服務器可用並正確配置也是宿主職責的一部分。你可以把宿主看作是服務器的包裝。宿主被配置為使用一個特定的服務器;服務器並不知道它的宿主。
設置宿主
使用 WebHostBuilder
實例創建一個宿主。這通常是在你的應用程序入口點:public static void Main
,(在項目模板的 Program.cs 文件中)。一個典型的 Program.cs 如下所示,演示如何使用 WebHostBuilder
來構建一個宿主。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}
WebHostBuilder
負責創建宿主,宿主會啟動應用程序服務器。WebHostBuilder
需要你提供實現了 IServer (上面代碼中的 UseKestrel
) 接口的服務器。 UseKestrel
指定應用程序會使用 Kestrel 服務器。
服務器的 內容根 ( content root ) 決定它將在哪里搜索內容文件,比如 MVC 視圖文件。默認的內容根是應用程序運行的文件夾。
注解
指定Directory.GetCurrentDirectory
作為內容根時,當應用程序啟動時會使用 Web 項目的根目錄作為應用程序的內容根(比如,從 Web 項目文件夾調用dotnet run
)。Visual Studio 和dotnet new
的模板是默認使用Directory.GetCurrentDirectory
作為內容根的。
如果應用程序需要使用 IIS,需要在構建宿主時調用 UseIISIntegration
方法。注意這不是像 UseKestrel
那樣配置一個 服務器。為了讓 ASP.NET Core 使用 IIS,你必須同時指定 UseKestrel
和 UseIISIntegration
。Kestrel 被設計為在代理后運行而不應該直接部署到互聯網。UseIISIntegration
指定 IIS 為反向代理服務器。
注解
UseKestrel
與UseIISIntegration
行為區別非常大。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();
注解
當設置一個宿主,你可以提供Configure
和ConfigureServices
方法,或者定義一個Startup
類(也必須定義這些方法,參見 :doc:startup
)。多次調用ConfigureServices
會進行追加配置;多次調用Configure
或者UseStartup
會替換之前的設置。
配置宿主
WebHostBuilder
提供了方法用於為宿主設置大多數可用的配置值,它也可以被設置為直接使用 UseSetting
以及相關的鍵。比如,指定應用程序名字:
new WebHostBuilder()
.UseSetting("applicationName", "MyApp")
宿主配置值
應用程序名 string
鍵: applicationName
。這個配置設定指定的值將從 IHostingEnvironment.ApplicationName
返回。
捕獲啟動異常 bool
鍵: captureStartupErrors
。默認是 false
。當值為 false
時,在啟動過程中的錯誤會導致宿主退出。當值為 true
時,宿主會捕捉 Startup
類中的任何異常,並試圖啟動服務器。同時將為每個請求顯示錯誤頁面(一般的,或詳細的,這取決於下面提到的詳細錯誤設置)。 可使用 CaptureStartupErrors
方法設置。
new WebHostBuilder()
.CaptureStartupErrors(true)
內容根 string
Key: contentRoot
。默認是應用程序集所在的文件夾(針對 Kestrel;IIS 默認使用 Web 項目根目錄)。這個設置決定了 ASP.NET Core 從哪里開始搜索內容文件,比如 MVC 視圖。內容根同時被作為 Web 根設置 的基礎路徑使用。可使用 UseContentRoot
方法設置。路徑必須是存在的,否則宿主會啟動失敗。
new WebHostBuilder()
.UseContentRoot("c:\\mywebsite")
詳細錯誤 bool
鍵: detailedErrors
。默認是 false
。當值是 true
時(或者當環境設置為“Development”時),應用程序會顯示詳細的啟動錯誤信息,而不僅僅是一般的錯誤頁。可使用 UseSetting
設置。
new WebHostBuilder()
.UseSetting("detailedErrors", "true")
當詳細錯誤設置為 false
並且捕捉啟動異常是 true
時,服務器在每個請求的(錯誤)響應中顯示一般錯誤頁。
當詳細錯誤設置為 true
並且捕捉啟動異常是 true
時,服務器在每個請求的(錯誤)響應中顯示詳細錯誤頁。
環境 string
鍵: environment
。默認是“Production”。可以設置為任何值。框架定義的值包含“Development”,“Staging”,以及“Production”。值不區分大小寫。參見 environments。可使用 UseEnvironment
方法設置。
new WebHostBuilder()
.UseEnvironment("Development")
注解
默認情況下,環境是從ASPNETCORE_ENVIRONMENT
環境變量中讀取。當使用 Visual Studio,環境變量可能在 launchSettings.json 文件中進行設置。
服務器 URLs string
鍵: urls
。設置分號(;)來分隔服務器應該響應的 URL 前綴。比如,"http://localhost:123"。域名可以用“”替換,表明服務器需要針對任何使用指定端口及協議的 IP 地址或域名監聽請求(比如,“http://:5000”或者 “https://*:5001”)。協議(“http://”或者“https://”)必須包含在每個URL里。前綴由配置好的服務器解釋;服務器之間支持的格式會有所不同。
new WebHostBuilder()
.UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")
啟動程序集 string
鍵: startupAssembly
。決定搜索 Startup
類的程序集。可使用 UseStartup
方法設置。可以使用 WebHostBuilder.UseStartup<StartupType>
指定特定的引用類型。如果調用多次 UseStartup
方法,最后一個調用的生效。
new WebHostBuilder()
.UseStartup("StartupAssemblyName")
Web 根 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 文件中進行配置。要指定在特定的網址上運行宿主,你可以從命令行傳遞所需要的值:
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();
}
排序的重要性
WebHostBuilder
首先讀取某些環境變量中的設置(如果環境變量中設置了)。這些環境變量必須采用格式 ASPNETCORE_{configurationKey}
,因此假如要設置默認情況下服務器監聽的 URL,你需要設置 ASPNETCORE_URLS
。
你可以通過指定配置來重寫任何環境變量(使用 UseConfiguration
)或者明確地設置值(例如使用 UseUrls
)。宿主會使用任何選項最后設置的值。因此,UseIISIntegration
必須出現在 UseUrls
之后,因為它將替換 IIS 動態提供的 URL。如果你想以編程方式設置默認 URL 的值,但是允許他通過配置重寫,你需要如下配置宿主:
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
var host = new WebHostBuilder()
.UseUrls("http://*:1000") // default URL
.UseConfiguration(config) // override from command line
.UseKestrel()
.Build();
額外的資源
- Publishing to IIS
- Publish to a Linux Production Environment
- Hosting ASP.NET Core as a Windows Service
- Hosting ASP.NET Core Embedded in Another Application