ASP.NET Core Web主機(IWebHostBuilder)


1.前言

ASP.NET Core應用程序可以配置和啟動主機(Host)。主機負責應用程序啟動和生存期管理,配置服務器和請求處理管道。主機還可以設置日志記錄、依賴關系注入和配置。而host主機又包括Web主機(IWebHostBuilder)和通用主機(IHostBuilder)。該章節主要介紹了用於托管Web應用的Web主機。對於其他類型的應用,請使用通用主機。

2.設置主機

創建使用IWebHostBuilder實例的主機。通常在應用程序的入口點來執行Main方法。在項目模板中,Main位於Program.cs。典型應用默認調用CreateDefaultBuilder來開始創建主機:

1. public class Program 2. { 3. public static void Main(string[] args) 4. { 5. CreateWebHostBuilder(args).Build().Run(); 6. } 7. public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 8. WebHost.CreateDefaultBuilder(args) 9. .UseStartup<Startup>(); 10. } 

2.1執行下列任務

調用CreateDefaultBuilder的代碼位於名為CreateWebHostBuilder的方法中,這讓它區分於 Main中對生成器對象調用Run的代碼。CreateDefaultBuilder執行下列任務:
●使用應用程序的托管配置提供應用程序將Kestrel服務器配置為Web服務器。
●將內容根設置為由 Directory.GetCurrentDirectory返回的路徑。
●通過以下對象加載主機配置:
○前綴為ASPNETCORE_的環境變量(例如,ASPNETCORE_ENVIRONMENT)。
○命令行參數。
●按以下順序加載應用程序配置:
○appsettings.json。
○appsettings.{Environment}.json。
○應用在使用入口程序集的Development環境中運行時的機密管理器。
○環境變量。
○命令行參數。
●配置控制台和調試輸出的日志記錄。日志記錄包含appsettings.json或appsettings.{Environment}.json文件的日志記錄配置部分中指定的日志篩選規則。
●使用ASP.NET Core模塊在IIS后面運行時,CreateDefaultBuilder會啟用IIS集成,這會配置應用程序的基址和端口。IIS集成還配置應用程序以捕獲啟動錯誤。
●如果應用環境為“開發(Development)”,請將ServiceProviderOptions.ValidateScopes設為true。

2.2重寫和增強定義的配置

ConfigureAppConfiguration、ConfigureLogging以及IWebHostBuilder的其他方法和擴展方法可重寫和增強CreateDefaultBuilder定義的配置。下面是一些示例:
ConfigureAppConfiguration:用於指定應用的其他IConfiguration。下面的ConfigureAppConfiguration調用添加委托,以在appsettings.xml文件中添加應用配置,該示例在Core系列第11章節有演示。可多次調用ConfigureAppConfiguration。請注意,此配置不適用於主機(例如,服務器URL或環境)。


1. public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 2. WebHost.CreateDefaultBuilder(args) 3. .ConfigureAppConfiguration((hostingContext, config) => 4. { 5. config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true); 6. }); 

ConfigureLogging:ConfigureLogging調用添加委托,將最小日志記錄級別 (SetMinimumLevel)配置為LogLevel.Warning。此設置重寫CreateDefaultBuilder在appsettings.Development.json和appsettings.Production.json中配置,分別為LogLevel.Debug和LogLevel.Error。可多次調用 ConfigureLogging。

1. public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 2. WebHost.CreateDefaultBuilder(args) 3. .ConfigureLogging(logging => 4. { 5. logging.SetMinimumLevel(LogLevel.Warning); 6. }); 

ConfigureKestrel:調用ConfigureKestrel來重寫CreateDefaultBuilder在配置Kestrel時建立的30,000,000字節默認Limits.MaxRequestBodySize:

1. public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 2. WebHost.CreateDefaultBuilder(args) 3. .ConfigureKestrel((context, options) => 4. { 5. options.Limits.MaxRequestBodySize = ; 6. }); 

設置主機時,可以提供配置和ConfigureServices方法。如果指定Startup類,必須定義Configure方法。

3.主機配置值

WebHostBuilder依賴於以下的方法設置主機配置值:
●主機生成器配置,其中包括格式ASPNETCORE_{configurationKey}的環境變量。例如 ASPNETCORE_ENVIRONMENT。
●UseContentRoot和UseConfiguration等擴展。
●UseSetting和關聯鍵。使用UseSetting設置值時,該值設置為無論何種類型的字符串。

3.1應用程序鍵(名稱)

在主機構造期間調用UseStartup或Configure時,會自動設置 IHostingEnvironment.ApplicationName屬性。該值設置為包含應用入口點的程序集的名稱。要顯式設置值,請使用WebHostDefaults.ApplicationKey(環境變量:ASPNETCORE_APPLICATIONNAME):

1. public void Configure(IApplicationBuilder app, IHostingEnvironment env) 2. { 3. //應用程序默認名稱為:CoreWeb (也就是項目名稱) 4. string an = env.ApplicationName; 5. ...} 6. public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 7. WebHost.CreateDefaultBuilder(args).UseStartup<Startup>() 8. .UseSetting(WebHostDefaults.ApplicationKey, "CoreWeb"); 

3.2捕獲啟動錯誤

此設置控制啟動錯誤的捕獲。當false時,啟動期間出錯導致主機退出。當true時,主機在啟動期間捕獲異常並嘗試啟動服務器。(環境變量:ASPNETCORE_CAPTURESTARTUPERRORS)

1.  WebHost.CreateDefaultBuilder(args) 2. .CaptureStartupErrors(true) 

3.3內容根

此設置確定ASP.NET Core開始搜索內容文件,如MVC視圖等。內容根也用作Web根設置的基路徑。如果路徑不存在,主機將無法啟動。(環境變量:ASPNETCORE_CONTENTROOT)

1.  WebHost.CreateDefaultBuilder(args) 2. .UseContentRoot("c:\\<content-root>") 

3.4詳細錯誤

確定是否應捕獲詳細錯誤。啟用(或當環境設置為Development)時,應用捕獲詳細的異常。(環境變量:ASPNETCORE_DETAILEDERRORS)

1.  WebHost.CreateDefaultBuilder(args) 2. .UseSetting(WebHostDefaults.DetailedErrorsKey, "true") 

3.5環境

設置應用程序的環境。環境可以設置為任何值。框架定義的值包括Development、Staging和Production。值不區分大小寫。默認情況下,從ASPNETCORE_ENVIRONMENT環境變量讀取環境。使用Visual Studio時,可能會在launchSettings.json文件中設置環境變量。有關於環境詳情信息,可以移步到Core系列第10章節有參閱。(環境變量:ASPNETCORE_ENVIRONMENT)

1.  WebHost.CreateDefaultBuilder(args) 2. .UseEnvironment(EnvironmentName.Development) 

3.6HTTPS端口

設置HTTPS重定向端口。用於強制實施HTTPS。(環境變量:ASPNETCORE_HTTPS_PORT)

1.  WebHost.CreateDefaultBuilder(args) 2. .UseSetting(") 

3.7服務器(Kestrel) URL

指示IP地址或主機地址,其中包含服務器應針對請求偵聽的端口和協議。設置為服務器應響應的以分號分隔 (;) 的URL前綴列表。例如 http://localhost:123。使用“”指示服務器應針對請求偵聽的使用特定端口和協議(例如 http://:5000)的IP地址或主機名。協議(http://或https://)必須包含每個URL。不同的服務器支持的格式有所不同。(環境變量:ASPNETCORE_URLS)

1.  WebHost.CreateDefaultBuilder(args)
2.  .UseUrls("https://*:5000;https://localhost:5001;https://hostname:5002")
 
image
 
image

4.重寫配置

使用配置可以配置Web主機。在下面的示例中,主機配置是根據需要在hostsettings.json文件中指定。命令行參數可能會重寫從hostsettings.json文件加載的任何配置。生成的配置(在config中)用於通過UseConfiguration配置主機。
新建一個hostsettings.json文件,內容如下:

1.  {
2.  "urls":  "https://*:5005"
3.  }
1. public static IWebHostBuilder CreateWebHostBuilder(string[] args) 2. { 3. //IConfigurationBuilder的配置主機 4. var config = new ConfigurationBuilder() 5. .SetBasePath(Directory.GetCurrentDirectory()) 6. //主機配置在hostsettings.json文件中指定 7. .AddJsonFile("hostsettings.json", optional: true) 8. //輸入的命令行參數可能會重寫從hostsettings.json文件加載的任何配置 9. .AddCommandLine(args) 10. .Build(); 12. return WebHost.CreateDefaultBuilder(args) 13. .UseUrls("https://*:5001") 14. .UseConfiguration(config) 15. .Configure(app => 16. { 17. //生成的配置委托函數 18. app.Run(context => 19. context.Response.WriteAsync("Hello, World!")); 20. }); 21. } 

上述代碼描述意思是若要指定在特定的URL上運行的主機,所需的值可以在執行dotnet運行時從命令提示符傳入。命令行參數重寫hostsettings.json文件中的urls值,且服務器偵聽端口8080:

1.  dotnet run --urls "http://*:8080"

主機啟動時,先用hostsettings.json config重寫UseUrls提供的urls參數配置,然后再用命令行參數config重寫hostsettings.json config的urls參數配置。

5.管理主機

管理主題啟動方式有Run和Start兩種。Run方法啟動Web應用程序並阻止調用線程,直到關閉主機。Start方法通過調用自身以非阻止方式運行主機。

1. //Run 2. CreateWebHostBuilder(args).Build().Run(); 
1. //Start:非阻止方式,所有必須加上ReadLine 2. CreateWebHostBuilder(args).Build().Start(); 3. Console.ReadLine(); 

6.IHostingEnvironment接口

IHostingEnvironment接口提供有關應用的Web承載環境的信息。使用構造函數注入獲取 IHostingEnvironment以使用其屬性和擴展方法:

1. //示例1: 2. public class CustomFileReader 3. { 4. private readonly IHostingEnvironment _env; 6. public CustomFileReader(IHostingEnvironment env) 7. { 8. _env = env; 9. } 10. public string ReadFile(string filePath) 11. { 12. var fileProvider = _env.WebRootFileProvider; 13. // Process the file here 14. } 15. } 

可以用於在啟動時基於環境配置應用程序或者將IHostingEnvironment注入到Startup構造函數,用於ConfigureServices:

1. //示例2: 2. public class Startup 3. { 4. public Startup(IHostingEnvironment env) 5. { 6. HostingEnvironment = env; 7. } 8. public IHostingEnvironment HostingEnvironment { get; } 9. public void ConfigureServices(IServiceCollection services) 10. { 11. if (HostingEnvironment.IsDevelopment()) 12. { 13. // Development configuration 14. } 15. else 16. { 17. // Staging/Production configuration 18. } 19. var contentRootPath = HostingEnvironment.ContentRootPath; 20. } 21. } 

IHostingEnvironment服務還可以直接注入到Configure方法以設置處理管道:

1. //示例3: 2. public void Configure(IApplicationBuilder app, IHostingEnvironment env) 3. { 4. if (env.IsDevelopment()) 5. { 6. // In Development, use the Developer Exception Page 7. app.UseDeveloperExceptionPage(); 8. } 9. else 10. { 11. // In Staging/Production, route exceptions to /error 12. app.UseExceptionHandler("/error"); 13. } 14. var contentRootPath = env.ContentRootPath; 15. } 

創建自定義中間件(要了解中間件的同學們,可以移步到第四章節學習)時可以將IHostingEnvironment 注入Invoke方法:

1. public async Task Invoke(HttpContext context, IHostingEnvironment env) 2. { 3. if (env.IsDevelopment()) 4. { 5. // Configure middleware for Development 6. } 7. else 8. { 9. // Configure middleware for Staging/Production 10. } 11. var contentRootPath = env.ContentRootPath; 12. } 

7.IApplicationLifetime接口

IApplicationLifetime允許后啟動和關閉活動。接口上的三個屬性是用於注冊Action方法(用於定義啟動和關閉事件)的取消標記。

取消標記 | 觸發條件

ApplicationStarted | 主機已完全啟動。

ApplicationStopped | 主機正在完成正常關閉。應處理所有請求。 關閉受到阻止,直到完成此事件。

ApplicationStopping | 主機正在執行正常關閉。仍在處理請求。關閉受到阻止,直到完成此事件。

1. public class Startup 2. { 3. public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime) 4. { 5. appLifetime.ApplicationStarted.Register(OnStarted); 6. appLifetime.ApplicationStopping.Register(OnStopping); 7. appLifetime.ApplicationStopped.Register(OnStopped); 8. Console.CancelKeyPress += (sender, eventArgs) => 9. { 10. appLifetime.StopApplication(); 11. // Don't terminate the process immediately, wait for the Main thread to exit gracefully. 12. eventArgs.Cancel = true; 13. }; 14. } 15. private void OnStarted() 16. { 17. // Perform post-startup activities here 18. } 19. private void OnStopping() 20. { 21. // Perform on-stopping activities here 22. } 23. private void OnStopped() 24. { 25. // Perform post-stopped activities here 26. } 27. } 

StopApplication是請求應用終止的意思。以下類在調用類的Shutdown方法時使用StopApplication正常關閉應用:

1. public class MyClass 2. { 3. private readonly IApplicationLifetime _appLifetime; 4. public MyClass(IApplicationLifetime appLifetime) 5. { 6. _appLifetime = appLifetime; 7. } 8. public void Shutdown() 9. { 10. _appLifetime.StopApplication(); 11. } 12. } 

8.作用域驗證

如果應用環境為“開發(Development)”,則CreateDefaultBuilder將ServiceProviderOptions.ValidateScopes設為true。若將ValidateScopes設為true,默認服務提供應用程序會執行檢查來驗證以下內容:
●作用域服務不能直接或間接地從根服務提供者解析。
●作用域服務不會直接或間接地注入到單例中(服務的生命周期)。
若要始終驗證作用域(包括在生命周期環境中驗證),請使用主機生成器上的 UseDefaultServiceProvider配置ServiceProviderOptions:


1. WebHost.CreateDefaultBuilder(args) 2. .UseDefaultServiceProvider((context, options) => { 3. options.ValidateScopes = true; 4. }) 


作者:小宇宙_fly
鏈接:https://www.jianshu.com/p/d7d1b471e80f
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM