主机(Host)
参考文档
主机 (Host) 是一个包含应用启动和生命周期管理的对象。
它在整个应用的运行期间负责配置和管理依赖项、配置选项、日志记录、应用生命周期事件等。
NET Core 中有两种主要的主机模型:
- Web 主机(Web Host): 专门用于 ASP.NET Core Web 应用,但随着 .NET Core 3.0 的发布,通用主机已经成为首选,Web 主机主要用于兼容旧版本。
- 通用主机(Generic Host): 可用于所有类型的应用程序(包括控制台应用、后台服务等)。
- WebApplication and WebApplicationBuilder :是 .NET 6 简化 ASP.NET Core Web 应用开发的核心组件。相较于之前的通用主机(Generic Host)和 Web 主机(Web Host),它们将构建主机、配置服务、设置请求管道的步骤整合在一起。
备注
Host的配置主要分为:
- Host相关配置:如服务器、日志等
- 依赖注入相关服务:如 MVC 控制器服务、第三方服务等。
- 添加中间件及管道:如使用授权中间件、路由匹配中间件等。
- 其他配置:如MapControllers等路由配置。
本文主要介绍Host相关配置,其他配置参考其他章节。
WebApplicationBuilder自定义实例化
可以通过代码设置content root、应用程序名称和环境。 Program.cs
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
Args = args,
// Look for static files in webroot
ApplicationName = typeof(Program).Assembly.FullName,
EnvironmentName = Environments.Development,
ContentRootPath = Directory.GetCurrentDirectory(),
WebRootPath = "customwwwroot"
});
其中:
Args: 将应用程序的命令行参数传递给构建器。这些参数通常是由用户在启动应用程序时提供的,可以用于进一步配置应用程序的行为。
可以通过配置服务(Configuration)来获取命令行参数:
var commandLineArgs = app.Configuration.GetCommandLineArgs();
EnvironmentName: 设置应用程序运行的环境。EnvironmentName 决定了应用程序在不同环境下的行为,比如不同的配置文件、日志级别等。
比如:
if (app.Environment.IsDevelopment())
{
// 开发环境下使用中间件
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "My API V1");
});
}
不推荐在代码中指定运行环境。一般在运行时由以下方式指定:
- 设置系统环境变量并运行
Windows:
set ASPNETCORE_ENVIRONMENT=Development && dotnet run
Linux/macOS:
ASPNETCORE_ENVIRONMENT=Development dotnet run
- 通过 launchSettings.json 指定
{
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
- 通过 Docker 环境变量指定 在 Dockerfile 中,可以像这样设置:
ENV ASPNETCORE_ENVIRONMENT=Production
或者在 docker-compose.yml 中指定:
services:
myapp:
image: myapp:latest
environment:
- ASPNETCORE_ENVIRONMENT=Production
- 通过 Azure App Service 配置
如果应用程序部署在 Azure App Service 上,你可以通过 Azure Portal 在“应用程序设置”中指定环境变量 ASPNETCORE_ENVIRONMENT,而不需要更改代码或配置文件。
优先级:
通过代码设置的 UseEnvironment() 方法优先级最高,其他方式根据上下文进行设置,通常是环境变量 > launchSettings.json > 默认。
ContentRootPath
ContentRoot 是应用程序的根目录,它包含应用程序的所有内容文件。通常,这个目录是应用程序启动时指定的,默认情况下就是应用程序运行的目录。例如:
- 代码文件:如 .cs 文件、配置文件(如 appsettings.json)。
- 静态资源:如果这些资源没有被单独放到 WebRoot 目录下。
- 视图文件:MVC 中的 .cshtml 文件。
可以通过 IHostEnvironment 或 IWebHostEnvironment 来获取它并用作业务处理。
// 通过 IWebHostEnvironment 获取 Content Root
var contentRootPath = app.Environment.ContentRootPath;
也可以使用依赖注入获取:
// 通过 IWebHostEnvironment 获取 Content Root
namespace WebApplicationDemo.Host
{
[Route("api/[controller]")]
[ApiController]
public class HostTestController : ControllerBase
{
[Route("GetWebHostEnvironment")]
[HttpGet]
public IActionResult GetWebHostEnvironment([FromServices] IWebHostEnvironment env)
{
return Content($"Content Root Path: {env.ContentRootPath}; ");
}
}
}
WebRootPath
WebRoot 是专门存放静态文件的目录。默认情况下,这个目录被命名为 wwwroot,其中包含应用程序的静态资源,例如:
- CSS 文件- JavaScript 文件- 图片- 其他前端资源
静态文件是指不需要服务器处理、直接由浏览器访问的文件,
ASP.NET Core 中可以通过中间件(UseStaticFiles)来配置静态文件服务,默认会将 WebRoot 目录下的文件公开给客户端访问。
WebRoot可以通过同样的 IWebHostEnvironment 来获取。
// 通过 IWebHostEnvironment 获取 Content Root
var contentRootPath = app.Environment.WebRootPath;
也可以使用依赖注入获取:
// 通过 IWebHostEnvironment 获取 Content Root
namespace WebApplicationDemo.Host
{
[Route("api/[controller]")]
[ApiController]
public class HostTestController : ControllerBase
{
[Route("GetWebHostEnvironment")]
[HttpGet]
public IActionResult GetWebHostEnvironment([FromServices] IWebHostEnvironment env)
{
return Content($"Web Root Path: {env.WebRootPath}; ");
}
}
}
端口设置
- Urls配置 Program.cs
// 方式一:启动时绑定
app.Run("http://localhost:3000");
// 方式二:启动前配置。可以绑定多个端口
app.Urls.Add("http://*:3000");
app.Urls.Add("http://*:9001");
从配置文件读取 Program.cs
var port = builder.Configuration["Port"] ?? "3000";
app.Urls.Add($"http://*:{port}");
appsettings.json/appsettings.{Environment}.json
{
"Port": 9002
}
- UseUrls()配置 Program.cs
builder.WebHost.UseUrls("http://*:9001");
- 通过ASPNETCORE_URLS环境变量设置 在项目目录下打开使用命令行设置并启动项目: windows:
set ASPNETCORE_URLS=http://localhost:5000
dotnet run
Linux/MacOS
export ASPNETCORE_URLS="http://localhost:5000"
dotnet run
::: warn 注意 该方式仅在当前命令行窗口生效 :::
- launchSettings.json配置 注意选择运行选项。
launchSettings.json
"http": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:9000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
- 使用dotnet —urls 命令行参数启动 在项目目录下打开使用命令行设置并启动项目:
dotnet run --urls http://localhost:7001;https://localhost:7011
以上各种方式优先级顺序为: 使用dotnet —urls 命令行参数启动 > launchSettings.json配置 > Urls配置 > UseUrls > 环境变量 > 默认值
.net 6以前版本的配置
.net 6以前版本使用ConfigureWebHostDefaults配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// 使用UseUrls设置监听的端口和协议
webBuilder.UseUrls("http://localhost:3001", "https://localhost:3002");
// 配置Kestrel服务
webBuilder.UseKestrel(kestrelServerOptions =>
{
kestrelServerOptions.ListenLocalhost(3001);
kestrelServerOptions.ListenLocalhost(3002, listenOptions => listenOptions.UseHttps());
});
});
配置文件
加载
在 .NET Core 应用程序中,appsettings.json 文件是一个常用的配置文件,用来存储应用程序的各种配置信息,比如数据库连接字符串、日志设置、环境变量等。
应用程序在启动时会自动加载并解析 appsettings.json 文件的内容,然后通过配置系统(IConfiguration)来访问这些数据。
在 ASP.NET Core 6.0+ 的最简化启动模式中,appsettings.json 是通过 WebApplicationBuilder 进行加载的。
WebApplicationBuilder 在创建时(WebApplication.CreateBuilder(args)
)默认会加载配置文件,并将配置存储在 IConfiguration 接口中。
访问
可以通过 builder.Configuration 来访问配置。
比如,空项目模板中有以下配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
可以使用以下代码来读取:
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
var logLevel = configuration["Logging:LogLevel:Default"]; // 获取嵌套属性
Console.WriteLine($"Default Log Level: {logLevel}");// 在启动的控制台输出:Default Log Level: Information
加载自定义配置文件
你可以手动添加其他配置文件,或者覆盖默认的 appsettings.json 文件。
然后使用 builder.Configuration.AddJsonFile()
方法可以加载自定义的配置文件。
var builder = WebApplication.CreateBuilder(args);
// 手动添加其他配置文件
builder.Configuration.AddJsonFile("customsettings.json", optional: true, reloadOnChange: true);
- optional: true 表示如果 customsettings.json 文件不存在,不会抛出异常。
- reloadOnChange: true 表示当文件发生更改时,会自动重新加载配置。
不同环境的配置
.NET Core 支持按环境加载不同的配置文件。你可以根据运行环境(如开发、测试或生产)定义不同的配置。
常见的环境有:
- Development(开发环境)
- Production(生产环境) 例如,在开发环境中,appsettings.Development.json 文件会被加载,用来覆盖 appsettings.json 中的配置。
使用命令行参数dotnet run --environment "Development"
可以指定环境。
加载的优先级顺序通常是:
- appsettings.json(基础配置)
- appsettings.{Environment}.json(根据环境覆盖配置)
- UserSecrets
- 环境变量
- 命令行参数
配置 Kestrel 服务器
Kestrel 是 ASP.NET Core 默认的跨平台 Web 服务器,用于处理 HTTP 请求。
通过 ConfigureKestrel 方法,你可以详细控制 Kestrel 服务器的行为,例如监听的端口、最大请求大小、超时设置等。
builder.WebHost.ConfigureKestrel(options =>
{
// 限制请求大小
options.Limits.MaxRequestBodySize = 10 * 1024 * 1024;
// 请求头读取超时时间
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
// 最大并发连接数
options.Limits.MaxConcurrentConnections = 100;
// WebSocket等升级连接的最大并发数
options.Limits.MaxConcurrentUpgradedConnections = 100;
//通过限制请求速率来防止 DoS 攻击:
//MinRequestBodyDataRate:设置请求体的最小数据传输速率。
//bytesPerSecond:最低传输速率(字节 / 秒)。
//gracePeriod:在此时间内,服务器不会强制执行速率限制
options.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
// 设置请求队列大小
// 请求行的最大长度
options.Limits.MaxRequestLineSize = 8192;
// 请求缓冲区的大小
options.Limits.MaxRequestBufferSize = 65536;
});
.net 6以前版本的配置
.net 6以前版本使用ConfigureWebHostDefaults配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// 配置Kestrel服务
webBuilder.UseKestrel(options =>
{
// 限制请求大小
options.Limits.MaxRequestBodySize = 10 * 1024 * 1024;
// 请求头读取超时时间
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(30);
// 最大并发连接数
options.Limits.MaxConcurrentConnections = 100;
// WebSocket等升级连接的最大并发数
options.Limits.MaxConcurrentUpgradedConnections = 100;
//通过限制请求速率来防止 DoS 攻击:
//MinRequestBodyDataRate:设置请求体的最小数据传输速率。
//bytesPerSecond:最低传输速率(字节 / 秒)。
//gracePeriod:在此时间内,服务器不会强制执行速率限制
options.Limits.MinRequestBodyDataRate =
new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
// 设置请求队列大小
// 请求行的最大长度
options.Limits.MaxRequestLineSize = 8192;
// 请求缓冲区的大小
options.Limits.MaxRequestBufferSize = 65536;
});
});