在.NET 6.0中設定WebHostBuilder

2022-07-26 12:02:28

大家好,我是張飛洪,感謝您的閱讀,我會不定期和你分享學習心得,希望我的文章能成為你成長路上的墊腳石,讓我們一起精進。

本章是《客製化ASP NET 6.0框架系列文章》的第五篇。在本章,我們將回答如何在.NET 6.0中設定WebHostBuilder。

在閱讀第4章「使用Kestrel設定和客製化HTTPS」時,您可能會產生一些疑問:

  1. 如何使用使用者加密機制將密碼傳遞到HTTPS設定?
  2. 您甚至可能想知道是否可以從Program.cs中獲取設定?

在本章,我們將通過WebHostBuilderContext這個知識點來解答上面的疑問。

1

還記得在第四章當中,我們在Program.cs這個檔案進行WebHostBuilder Kestrel的相關設定。當時我們使用使用者祕鑰(user secrets)來設定證書密碼,如以下程式碼段所示:

public class Program {     
public static void Main(string[] args)  
{         
    CreateHostBuilder(args).Build().Run();     
}     
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>  
{
    webBuilder.UseKestrel(options =>  {
        options.Listen(IPAddress.Loopback, 5000);                         
        options.Listen(IPAddress.Loopback, 5001,listenOptions  => { listenOptions.UseHttps("certificate.pfx","topsecret");  }); }).UseStartup();}); 
    } 
}

此程式碼段對於.NET 5.0和早期版本仍然有效,對於.NET 6.0中的幾乎所有Web專案也有效。但對於使用Web專案模板建立的專案無效,比如你可能通過以下命令列的方式建立專案:

dotnet new web -n HostBuilderConfig -o HostBuilderConfig

.NET 6.0以後的迷你API的Program.cs檔案程式碼如下所示:

var builder = WebApplication.CreateBuilder(args); 
var app = builder.Build(); 
app.MapGet("/", () => "Hello World!"); 
app.Run();

設定在迷你API中看起來是這樣的:

using System.Net; 
var builder = WebApplication.CreateBuilder(args); 
builder.WebHost.UseKestrel(options => { 
    options.Listen(IPAddress.Loopback, 5000);     
    options.Listen(IPAddress.Loopback, 5001, listenOptions => {   
        listenOptions.UseHttps("certificate.pfx","topsecret");
    });
});

下面的程式碼適用於.NET 6.0及以前版本中的所有專案模板。

.UseKestrel((host, options) => {     // ... })

第一個引數host是WebHostBuilderContext範例,可以使用它存取設定資訊。

builder.WebHost.UseKestrel((host, options) => {     
    var filename = host.Configuration.GetValue("AppSettings:certfilename", "");     
    var password = host.Configuration.GetValue("AppSettings:certpassword", "");     
        options.Listen(IPAddress.Loopback, 5000);     
        options.Listen(IPAddress.Loopback, 5001, listenOptions => {
            listenOptions.UseHttps(filename, password);         
        });
});

在本例中,我們使用冒號分隔符讀取Json組態檔裡的值,Json檔案如下所示:

{     
    "AppSettings": {"certfilename": "certificate.pfx", "certpassword": "topsecret" },     
    "Logging": { "LogLevel": { "Default": "Warning"}}, 
    "AllowedHosts": "\*" 
}

提示:上面是一個如何從json讀取設定來設定Kestrel的範例。切記不要在程式碼中儲存任何祕鑰憑證(credentials),而是從使用者祕鑰儲存庫中讀取金鑰。具體用法可以在專案資料夾中執行以下.NET CLI命令列進行設定:

dotnet user-secrets init 
dotnet user-secrets set "AppSettings:certfilename" "certificate.pfx" 
dotnet user-secrets set "AppSettings:certpassword" "topsecret"

以上也適用於環境變數:

SET APPSETTINGS_CERTFILENAME=certificate.pfx 
SET APPSETTINGS_CERTPASSWORD=topsecret

提示:由於使用者祕鑰的儲存僅用於本地開發,因此應通過環境變數將憑據傳遞給生產中的應用程式或類生產環境的應用程式。

2

以上過程應該如何操作呢?
不知道大家還記不記得 ASP.NET Core 1.0在Startup.cs裡的設定方法?當時主要是在StartUp類別建構函式中設定的,新增使用者憑證的過程類似,大家可以比對一下:

var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional:  true); 
if (env.IsDevelopment()) {
    builder.AddUserSecrets(); 
} 
builder.AddEnvironmentVariables(); 
Configuration = builder.Build();

這段程式碼現在封裝在CreateDefaultBuilder方法中,如下所示:

builder.ConfigureAppConfiguration((hostingContext, config) => {
var env = hostingContext.HostingEnvironment; 
config.AddJsonFile("appsettings.json",optional: true,reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional: true,reloadOnChange: true);     
    if (env.IsDevelopment()) {       
        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));        
        if (appAssembly != null) {  
            config.AddUserSecrets(appAssembly, optional: true);  
        }
    }     
    config.AddEnvironmentVariables();     
    if (args != null) { config.AddCommandLine(args); }
});

我們看到程式碼幾乎沒什麼變化,Kestrel支援appsettings.json的檔案設定或者使用環境變數指定埠、URL等。我們看下WebHost.cs裡的程式碼:

builder.UseKestrel((builderContext, options) => { 
    options.Configure(builderContext.Configuration.GetSection("Kestrel"));
})

以上程式碼通過appsettings.json檔案進行Kestrel相關設定:

"Kestrel": { "EndPoints": {"Http": { "Url": "http://localhost:5555" }} }

或者,可以使用以下環境變數來設定:

SET KESTREL_ENDPOINTS_HTTP_URL=http://localhost:5555

3

好,主體內容介紹差不多了,簡單回顧一下本章中介紹的內容:
在Program.cs檔案的設定方法中,我們可以通過lambda進行應用程式設定,這裡有一個重要的物件WebHostBuilderContext,該物件基本上可以滿足我們常用的各自設定需求。
在下一章中,我們將介紹託管模型的詳細資訊,包括不同的託管模型以及如何通過不同方式託管ASP.NET Core應用程式。