在.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": "//localhost:5555" }} }

或者,可以使用以下環境變數來配置:

SET KESTREL_ENDPOINTS_HTTP_URL=//localhost:5555

3

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