Skip to content

主机(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的配置主要分为:

  1. Host相关配置:如服务器、日志等
  2. 依赖注入相关服务:如 MVC 控制器服务、第三方服务等。
  3. 添加中间件及管道:如使用授权中间件、路由匹配中间件等。
  4. 其他配置:如MapControllers等路由配置。

本文主要介绍Host相关配置,其他配置参考其他章节。

WebApplicationBuilder自定义实例化

可以通过代码设置content root、应用程序名称和环境。 Program.cs

C#
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)来获取命令行参数:

C#
var commandLineArgs = app.Configuration.GetCommandLineArgs();

EnvironmentName: 设置应用程序运行的环境。EnvironmentName 决定了应用程序在不同环境下的行为,比如不同的配置文件、日志级别等。

比如:

C#
if (app.Environment.IsDevelopment())
{
    // 开发环境下使用中间件
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("v1/swagger.json", "My API V1");
    });
}

不推荐在代码中指定运行环境。一般在运行时由以下方式指定:

  1. 设置系统环境变量并运行

Windows:

cmd
set ASPNETCORE_ENVIRONMENT=Development && dotnet run

Linux/macOS:

bash
ASPNETCORE_ENVIRONMENT=Development dotnet run
  1. 通过 launchSettings.json 指定
json
{
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "MyApp": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
  1. 通过 Docker 环境变量指定 在 Dockerfile 中,可以像这样设置:
dockerfile
ENV ASPNETCORE_ENVIRONMENT=Production

或者在 docker-compose.yml 中指定:

yaml
services:
  myapp:
    image: myapp:latest
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
  1. 通过 Azure App Service 配置

如果应用程序部署在 Azure App Service 上,你可以通过 Azure Portal 在“应用程序设置”中指定环境变量 ASPNETCORE_ENVIRONMENT,而不需要更改代码或配置文件。

优先级:

通过代码设置的 UseEnvironment() 方法优先级最高,其他方式根据上下文进行设置,通常是环境变量 > launchSettings.json > 默认。

ContentRootPath

ContentRoot 是应用程序的根目录,它包含应用程序的所有内容文件。通常,这个目录是应用程序启动时指定的,默认情况下就是应用程序运行的目录。例如:

  • 代码文件:如 .cs 文件、配置文件(如 appsettings.json)。
  • 静态资源:如果这些资源没有被单独放到 WebRoot 目录下。
  • 视图文件:MVC 中的 .cshtml 文件。

可以通过 IHostEnvironment 或 IWebHostEnvironment 来获取它并用作业务处理。

C#
// 通过 IWebHostEnvironment 获取 Content Root
var contentRootPath = app.Environment.ContentRootPath;

也可以使用依赖注入获取:

C#
// 通过 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 来获取。

C#
// 通过 IWebHostEnvironment 获取 Content Root
var contentRootPath = app.Environment.WebRootPath;

也可以使用依赖注入获取:

C#
// 通过 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}; ");
        }
    }
}

端口设置

  1. Urls配置 Program.cs
C#
// 方式一:启动时绑定
app.Run("http://localhost:3000");

// 方式二:启动前配置。可以绑定多个端口
app.Urls.Add("http://*:3000");
app.Urls.Add("http://*:9001");

从配置文件读取 Program.cs

c#
var port = builder.Configuration["Port"] ?? "3000";
app.Urls.Add($"http://*:{port}");

appsettings.json/appsettings.{Environment}.json

json
{
  "Port": 9002
}
  1. UseUrls()配置 Program.cs
c#
builder.WebHost.UseUrls("http://*:9001");
  1. 通过ASPNETCORE_URLS环境变量设置 在项目目录下打开使用命令行设置并启动项目: windows:
bash
set ASPNETCORE_URLS=http://localhost:5000
dotnet run

Linux/MacOS

bash
export ASPNETCORE_URLS="http://localhost:5000"
dotnet run

::: warn 注意 该方式仅在当前命令行窗口生效 :::

  1. launchSettings.json配置 注意选择运行选项。

launchSettings.json

json
"http": {
  "commandName": "Project",
  "launchBrowser": true,
  "applicationUrl": "https://localhost:9000",
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }
}
  1. 使用dotnet —urls 命令行参数启动 在项目目录下打开使用命令行设置并启动项目:
bash
dotnet run --urls http://localhost:7001;https://localhost:7011

以上各种方式优先级顺序为: 使用dotnet —urls 命令行参数启动 > launchSettings.json配置 > Urls配置 > UseUrls > 环境变量 > 默认值

.net 6以前版本的配置

.net 6以前版本使用ConfigureWebHostDefaults配置

C#
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": "*"
}

可以使用以下代码来读取:

C#
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()方法可以加载自定义的配置文件。

C#
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"可以指定环境。

加载的优先级顺序通常是:

  1. appsettings.json(基础配置)
  2. appsettings.{Environment}.json(根据环境覆盖配置)
  3. UserSecrets
  4. 环境变量
  5. 命令行参数

配置 Kestrel 服务器

Kestrel 是 ASP.NET Core 默认的跨平台 Web 服务器,用于处理 HTTP 请求。

通过 ConfigureKestrel 方法,你可以详细控制 Kestrel 服务器的行为,例如监听的端口、最大请求大小、超时设置等。

C#
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配置

C#
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; 
            });
        });

Document Base on VitePress.