ASP.NET Core 基础知识概述
注意
此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本。
本文概述了生成 ASP.NET Core 应用的基础知识,包括依赖关系注入 (DI)、配置、中间件等等。
Program.cs
使用 Web 模板创建的 ASP.NET Core 应用包含 Program.cs
文件中的应用程序启动代码。 Program.cs
文件位于:
- 已配置应用所需的服务。
- 应用的请求处理管道定义为一系列中间件组件。
以下应用启动代码支持:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapGet("/hi", () => "Hello!");
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
依赖关系注入(服务)
ASP.NET Core 包含依赖关系注入 (DI),可在应用中提供配置的服务。 使用以上代码中的 WebApplicationBuilder.Services、builder.Services
将服务添加到 DI 容器。 实例化 WebApplicationBuilder 时,会添加许多框架提供的服务。 在以下代码中,builder
是一个 WebApplicationBuilder
:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
在以上突出显示的代码中,builder
已将配置、日志记录和许多其他服务 添加到 DI 容器中。
以下代码将 Razor Pages、带视图的 MVC 控制器和自定义 DbContext 添加到 DI 容器:
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("RPMovieContext")));
var app = builder.Build();
通常使用构造函数注入从 DI 解析服务。 DI 框架在运行时提供此服务的实例。
以下代码使用构造函数注入从 DI 解析数据库上下文和记录器:
public class IndexModel : PageModel
{
private readonly RazorPagesMovieContext _context;
private readonly ILogger<IndexModel> _logger;
public IndexModel(RazorPagesMovieContext context, ILogger<IndexModel> logger)
{
_context = context;
_logger = logger;
}
public IList<Movie> Movie { get;set; }
public async Task OnGetAsync()
{
_logger.LogInformation("IndexModel OnGetAsync.");
Movie = await _context.Movie.ToListAsync();
}
}
中间件
请求处理管道由一系列中间件组件组成。 每个组件在 HttpContext
上执行操作,调用管道中的下一个中间件或终止请求。
按照惯例,通过调用 Use{Feature}
扩展方法,向管道添加中间件组件。 添加到应用的中间件在以下代码中突出显示:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapGet("/hi", () => "Hello!");
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
有关详细信息,请参阅 ASP.NET Core 中间件。
主机
ASP.NET Core 应用在启动时构建主机。 主机封装应用的所有资源,例如:
- HTTP 服务器实现
- 中间件组件
- 日志记录
- 依赖关系注入 (DI) 服务
- 配置
有三个不同的主机能够运行 ASP.NET Core 应用:
- ASP.NET Core WebApplication,也称为最小主机
- .NET 泛型主机,与 ASP.NET Core 组合ConfigureWebHostDefaults
- ASP.NET Core WebHost
建议在所有 ASP.NET Core 模板中使用 ASP.NET Core WebApplication 和 WebApplicationBuilder 类型。 WebApplication
的行为与 .NET 泛型主机类似,并公开许多相同的接口,但需要较少的回调进行配置。 ASP.NET Core WebHost 仅适用于后向兼容性。
以下示例实例化 WebApplication
:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
WebApplicationBuilder.Build 方法使用一组默认选项配置主机,例如:
非 Web 方案
其他类型的应用可通过通用主机使用横切框架扩展,例如日志记录、依赖项注入 (DI)、配置和应用生命周期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机和 ASP.NET Core 中使用托管服务的后台任务。
Servers
ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器对应用的请求在表面上呈现为一组由 HttpContext
组成的请求功能。
ASP.NET Core 提供以下服务器实现:
- Kestrel 是跨平台 Web 服务器。 Kestrel 通常使用 IIS 在反向代理配置中运行。 在 ASP.NET Core 2.0 或更高版本中,Kestrel 可作为面向公众的边缘服务器运行,直接向 Internet 公开。
- IIS HTTP 服务器适用于使用 IIS 的 Windows。 借助此服务器,ASP.NET Core 应用和 IIS 在同一进程中运行。
- HTTP.sys是适用于不与 IIS 一起使用的 Windows 的服务器。
有关详细信息,请参阅 ASP.NET Core 中的 Web 服务器实现。
配置
ASP.NET Core 提供了配置框架,可以从配置提供程序的有序集中将设置作为名称/值对。 可将内置配置提供程序用于各种源,例如 .json
文件、.xml
文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。
默认情况下,ASP.NET Core 应用配置为从 appsettings.json
、环境变量和命令行等读取内容。 加载应用配置后,来自环境变量的值将替代来自 的值appsettings.json
。
为了管理密码等机密配置数据,.NET Core 提供了机密管理器。 对于生产机密,建议使用 Azure 密钥保管库。
有关详细信息,请参阅 ASP.NET Core 中的配置。
环境
执行环境(例如 Development
、Staging
和 Production
)在 ASP.NET Core 中可用。 通过设置 ASPNETCORE_ENVIRONMENT
环境变量来指定应用的运行环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment
实现中。 通过依赖关系注入 (DI),可以在应用中任何位置实现此操作。
以下示例未在 Development
环境中运行时配置异常处理程序和 HTTP 严格传输安全协议 (HSTS) 中间件:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.MapGet("/hi", () => "Hello!");
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.Run();
有关详细信息,请参阅在 ASP.NET Core 中使用多个环境。
日志记录
ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:
- 控制台
- 调试
- Windows 事件跟踪
- Windows 事件日志
- TraceSource
- Azure 应用服务
- Azure Application Insights
若要创建服务,请从依赖关系注入 (DI) 解析 ILogger<TCategoryName> 服务,并调用 LogInformation 等日志记录方法。 例如:
public class IndexModel : PageModel
{
private readonly RazorPagesMovieContext _context;
private readonly ILogger<IndexModel> _logger;
public IndexModel(RazorPagesMovieContext context, ILogger<IndexModel> logger)
{
_context = context;
_logger = logger;
}
public IList<Movie> Movie { get;set; }
public async Task OnGetAsync()
{
_logger.LogInformation("IndexModel OnGetAsync.");
Movie = await _context.Movie.ToListAsync();
}
}
有关详细信息,请参阅 .NET Core 和 ASP.NET Core 中的日志记录。
路由
路由是映射到处理程序的 URL 模式。 处理程序通常是 Razor 页面、MVC 控制器中的操作方法或中间件。 借助 ASP.NET Core 路由,可以控制应用使用的 URL。
以下由 ASP.NET Core Web 应用程序模板生成的代码调用 UseRouting:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
有关详细信息,请参阅 ASP.NET Core 中的路由。
错误处理。
ASP.NET Core 具有用于处理错误的内置功能,例如:
- 开发人员异常页
- 自定义错误页
- 静态状态代码页
- 启动异常处理
有关详细信息,请参阅处理 ASP.NET Core 中的错误。
发出 HTTP 请求
IHttpClientFactory
的实现可用于创建 HttpClient
实例。 工厂可以:
- 提供一个中心位置,用于命名和配置逻辑
HttpClient
实例。 例如,注册并配置 github 客户端以访问 GitHub。 注册并配置默认客户端以实现其他目的。 - 支持多个委托处理程序的注册和链接,以生成出站请求中间件管道。 此模式类似于 ASP.NET Core 的入站中间件管道。 此模式提供了一种用于管理 HTTP 请求相关问题的机制,包括缓存、错误处理、序列化以及日志记录。
- 与 Polly 集成,这是用于瞬时故障处理的常用第三方库。
- 管理基础
HttpClientHandler
实例的池和生存期,避免手动管理HttpClient
生存期时可能出现的常见 DNS 问题。 - 通过 ILogger 添加可配置的日志记录体验,用于记录通过工厂创建的客户端发送的所有请求。
有关详细信息,请参阅在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求。
内容根
内容根目录是指向以下内容的基路径:
- 托管应用的可执行文件 (.exe)。
- 构成应用程序的已编译程序集 (.dll)。
- 应用使用的内容文件,例如:
- Razor 文件(
.cshtml
、.razor
) - 配置文件(
.json
、.xml
) - 数据文件 (
.db
)
- Razor 文件(
- Web 根目录,通常是 wwwroot 文件夹。
在开发中,内容根目录默认为项目的根目录。 此目录还是应用内容文件和 Web 根目录的基路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅内容根。
Web 根
Web 根目录是公用静态资源文件的基路径,例如:
- 样式表 (
.css
) - JavaScript (
.js
) - 图像(
.png
、.jpg
)
默认情况下,静态文件仅从 Web 根目录及其子目录提供。 Web 根目录路径默认为 {content root}/wwwroot。 在构建主机时设置路径,可指定不同的 Web 根目录。 有关详细信息,请参阅 Web 根目录。
防止使用项目文件中的 <Content> 项目项在 wwwroot 中发布文件。 下面的示例会阻止在 wwwroot/local 及其子目录中发布内容:
<ItemGroup>
<Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>
在 Razor.cshtml
文件中,~/
指向 Web 根。 以 ~/
开头的路径称为虚拟路径。
有关详细信息,请参阅 ASP.NET Core 中的静态文件。
其他资源
本文概述了生成 ASP.NET Core 应用的基础知识,包括依赖关系注入 (DI)、配置、中间件等等。
Startup 类
Startup
类位于:
- 已配置应用所需的服务。
- 应用的请求处理管道定义为一系列中间件组件。
下面是 Startup
类示例:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<RazorPagesMovieContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("RazorPagesMovieContext")));
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
});
}
}
有关详细信息,请参阅 ASP.NET Core 中的应用启动。
依赖关系注入(服务)
ASP.NET Core 有内置的依赖关系注入 (DI) 框架,可在应用中提供配置的服务。 例如,日志记录组件就是一项服务。
将配置(或注册)服务的代码添加到 Startup.ConfigureServices
方法中。 例如:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<RazorPagesMovieContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("RazorPagesMovieContext")));
services.AddControllersWithViews();
services.AddRazorPages();
}
通常使用构造函数注入从 DI 解析服务。 通过构造函数注入,有一个类声明请求的类型或接口的构造函数参数。 DI 框架在运行时提供此服务的实例。
以下示例使用构造函数注入从 DI 解析 RazorPagesMovieContext
:
public class IndexModel : PageModel
{
private readonly RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovieContext context)
{
_context = context;
}
// ...
public async Task OnGetAsync()
{
Movies = await _context.Movies.ToListAsync();
}
}
如果内置控制反转 (IoC) 容器不能满足应用的所有需求,可以改用第三方 IoC。
有关详细信息,请参阅 ASP.NET Core 中的依赖项注入。
中间件
请求处理管道由一系列中间件组件组成。 每个组件在 HttpContext
上执行操作,调用管道中的下一个中间件或终止请求。
按照惯例,通过在 Startup.Configure
方法中调用 Use...
扩展方法,向管道添加中间件组件。 例如,要启用静态文件的呈现,请调用 UseStaticFiles
。
以下示例配置了请求处理管道:
public void Configure(IApplicationBuilder app)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
});
}
ASP.NET Core 包含一组丰富的内置中间件。 也可编写自定义中间件组件。
有关详细信息,请参阅 ASP.NET Core 中间件。
主机
ASP.NET Core 应用在启动时构建主机。 主机封装应用的所有资源,例如:
- HTTP 服务器实现
- 中间件组件
- 日志记录
- 依赖关系注入 (DI) 服务
- 配置
有两个不同的主机:
- .NET 通用主机
- ASP.NET Core Web 主机
建议使用 .NET 通用主机。 ASP.NET Core Web 主机仅用于支持后向兼容性。
以下示例将创建 .NET 通用主机:
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.UseStartup<Startup>();
});
}
CreateDefaultBuilder
和 ConfigureWebHostDefaults
方法为主机配置一组默认选项,例如:
- 将 Kestrel 用作 Web 服务器并启用 IIS 集成。
- 从
appsettings.json
、appsettings.{Environment}.json
、环境变量、命令行参数和其他配置源中加载配置。 - 将日志记录输出发送到控制台并调试提供程序。
有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机。
非 Web 方案
其他类型的应用可通过通用主机使用横切框架扩展,例如日志记录、依赖项注入 (DI)、配置和应用生命周期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机和 ASP.NET Core 中使用托管服务的后台任务。
Servers
ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器对应用的请求在表面上呈现为一组由 HttpContext
组成的请求功能。
ASP.NET Core 提供以下服务器实现:
- Kestrel 是跨平台 Web 服务器。 Kestrel 通常使用 IIS 在反向代理配置中运行。 在 ASP.NET Core 2.0 或更高版本中,Kestrel 可作为面向公众的边缘服务器运行,直接向 Internet 公开。
- IIS HTTP 服务器适用于使用 IIS 的 Windows。 借助此服务器,ASP.NET Core 应用和 IIS 在同一进程中运行。
- HTTP.sys是适用于不与 IIS 一起使用的 Windows 的服务器。
有关详细信息,请参阅 ASP.NET Core 中的 Web 服务器实现。
配置
ASP.NET Core 提供了配置框架,可以从配置提供程序的有序集中将设置作为名称/值对。 可将内置配置提供程序用于各种源,例如 .json
文件、.xml
文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。
默认情况下,ASP.NET Core 应用配置为从 appsettings.json
、环境变量和命令行等读取内容。 加载应用配置后,来自环境变量的值将替代来自 的值appsettings.json
。
读取相关配置值的首选方法是使用选项模式。 有关详细信息,请参阅使用选项模式绑定分层配置数据。
为了管理密码等机密配置数据,.NET Core 提供了机密管理器。 对于生产机密,建议使用 Azure 密钥保管库。
有关详细信息,请参阅 ASP.NET Core 中的配置。
环境
执行环境(例如 Development
、Staging
和 Production
)是 ASP.NET Core 中的高级概念。 通过设置 ASPNETCORE_ENVIRONMENT
环境变量来指定应用的运行环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment
实现中。 通过依赖关系注入 (DI),可以在应用中任何位置实现此操作。
使用以下示例配置应用,应用在 Development
环境中运行时将提供详细错误信息:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
});
}
有关详细信息,请参阅在 ASP.NET Core 中使用多个环境。
日志记录
ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:
- 控制台
- 调试
- Windows 事件跟踪
- Windows 事件日志
- TraceSource
- Azure 应用服务
- Azure Application Insights
若要创建服务,请从依赖关系注入 (DI) 解析 ILogger<TCategoryName> 服务,并调用 LogInformation 等日志记录方法。 例如:
public class TodoController : ControllerBase
{
private readonly ILogger _logger;
public TodoController(ILogger<TodoController> logger)
{
_logger = logger;
}
[HttpGet("{id}", Name = "GetTodo")]
public ActionResult<TodoItem> GetById(string id)
{
_logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
// Item lookup code removed.
if (item == null)
{
_logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
return NotFound();
}
return item;
}
}
LogInformation
等日志记录方法支持任意数量的字段。 这些字段通常用于构造消息 string
,但某些日志记录提供程序会将它们作为独立字段发送到数据存储。 此功能使日志提供程序可以实现语义日志记录,也称为结构化日志记录。
有关详细信息,请参阅 .NET Core 和 ASP.NET Core 中的日志记录。
路由
路由是映射到处理程序的 URL 模式。 处理程序通常是 Razor 页面、MVC 控制器中的操作方法或中间件。 借助 ASP.NET Core 路由,可以控制应用使用的 URL。
有关详细信息,请参阅 ASP.NET Core 中的路由。
错误处理。
ASP.NET Core 具有用于处理错误的内置功能,例如:
- 开发人员异常页
- 自定义错误页
- 静态状态代码页
- 启动异常处理
有关详细信息,请参阅处理 ASP.NET Core 中的错误。
发出 HTTP 请求
IHttpClientFactory
的实现可用于创建 HttpClient
实例。 工厂可以:
- 提供一个中心位置,用于命名和配置逻辑
HttpClient
实例。 例如,注册并配置 github 客户端以访问 GitHub。 注册并配置默认客户端以实现其他目的。 - 支持多个委托处理程序的注册和链接,以生成出站请求中间件管道。 此模式类似于 ASP.NET Core 的入站中间件管道。 此模式提供了一种用于管理 HTTP 请求相关问题的机制,包括缓存、错误处理、序列化以及日志记录。
- 与 Polly 集成,这是用于瞬时故障处理的常用第三方库。
- 管理基础
HttpClientHandler
实例的池和生存期,避免手动管理HttpClient
生存期时可能出现的常见 DNS 问题。 - 通过 ILogger 添加可配置的日志记录体验,用于记录通过工厂创建的客户端发送的所有请求。
有关详细信息,请参阅在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求。
内容根
内容根目录是指向以下内容的基路径:
- 托管应用的可执行文件 (.exe)。
- 构成应用程序的已编译程序集 (.dll)。
- 应用使用的内容文件,例如:
- Razor 文件(
.cshtml
、.razor
) - 配置文件(
.json
、.xml
) - 数据文件 (
.db
)
- Razor 文件(
- Web 根目录,通常是 wwwroot 文件夹。
在开发中,内容根目录默认为项目的根目录。 此目录还是应用内容文件和 Web 根目录的基路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅内容根。
Web 根
Web 根目录是公用静态资源文件的基路径,例如:
- 样式表 (
.css
) - JavaScript (
.js
) - 图像(
.png
、.jpg
)
默认情况下,静态文件仅从 Web 根目录及其子目录提供。 Web 根目录路径默认为 {content root}/wwwroot。 在构建主机时设置路径,可指定不同的 Web 根目录。 有关详细信息,请参阅 Web 根目录。
防止使用项目文件中的 <Content> 项目项在 wwwroot 中发布文件。 下面的示例会阻止在 wwwroot/local 及其子目录中发布内容:
<ItemGroup>
<Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>
在 Razor.cshtml
文件中,波形符-斜线 (~/
) 指向 Web 根。 以 ~/
开头的路径称为虚拟路径。
有关详细信息,请参阅 ASP.NET Core 中的静态文件。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈