大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。
本章是《定制ASP NET 6.0框架系列文章》的第五篇。在本章,我们将回答如何在.NET 6.0中配置WebHostBuilder。
在阅读第4章“使用Kestrel配置和定制HTTPS”时,您可能会产生一些疑问:
- 如何使用用户加密机制将密码传递到HTTPS配置?
- 您甚至可能想知道是否可以从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应用程序。