ASP.NET Core 基础知识概述

Note

此版本不是本文的最新版本。 对于当前版本,请参阅本文的 .NET 9 版本

Warning

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 NET Core 支持策略。 对于当前版本,请参阅本文的 .NET 9 版本

Important

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

对于当前版本,请参阅本文的 .NET 9 版本

本文概述了生成 ASP.NET Core 应用的基础知识,包括依赖关系注入 (DI)、配置、中间件等等。

有关补充或取代本文中的指南的 Blazor 基础知识指南,请参阅 ASP.NET Core Blazor 基础知识

Program.cs

使用 Web 模板创建的 ASP.NET Core 应用包含 Program.cs 文件中的应用程序启动代码。 Program.cs 文件位于:

  • 已配置应用所需的服务。
  • 应用的请求处理管道定义为一系列 中间件组件

以下应用启动代码支持多种应用类型:

using WebAll.Components;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();
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.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.UseAntiforgery();

app.Run();

依赖关系注入(服务)

ASP.NET 核心功能内置 依赖项注入(DI),使配置的服务在整个应用中可用。 在前面的代码中使用 WebApplicationBuilder.Servicesbuilder.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();

在前面的代码中,CreateBuilder 向 DI 容器添加配置、日志记录和 许多其他 服务。 DI 框架在运行时提供所请求服务的实例。

以下代码将自定义 DbContext 和 Blazor 组件添加到 DI 容器:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MoviesContext") 
        ?? throw new InvalidOperationException("Connection string not found.")));

builder.Services.AddQuickGridEntityFrameworkAdapter();

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

在 Blazor Web App中,服务通常在运行时使用 @inject 组件中的 Razor 指令从 DI 进行解析,如以下示例所示:

@page "/movies"
@rendermode InteractiveServer
@using Microsoft.EntityFrameworkCore
@using Microsoft.AspNetCore.Components.QuickGrid
@using BlazorWebAppMovies.Models
@using BlazorWebAppMovies.Data
@implements IAsyncDisposable
@inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory

<PageTitle>Index</PageTitle>

<h1>Index</h1>

<div>
    <input type="search" @bind="titleFilter" @bind:event="oninput" />
</div>

<p>
    <a href="movies/create">Create New</a>
</p>

<QuickGrid Class="table" Items="FilteredMovies" Pagination="pagination">
    <PropertyColumn Property="movie => movie.Title" Sortable="true" />
    <PropertyColumn Property="movie => movie.ReleaseDate" Title="Release Date" />
    <PropertyColumn Property="movie => movie.Genre" />
    <PropertyColumn Property="movie => movie.Price" />
    <PropertyColumn Property="movie => movie.Rating" />

    <TemplateColumn Context="movie">
        <a href="@($"movies/edit?id={movie.Id}")">Edit</a> |
        <a href="@($"movies/details?id={movie.Id}")">Details</a> |
        <a href="@($"movies/delete?id={movie.Id}")">Delete</a>
    </TemplateColumn>
</QuickGrid>

<Paginator State="pagination" />

@code {
    private BlazorWebAppMoviesContext context = default!;
    private PaginationState pagination = new PaginationState { ItemsPerPage = 10 };
    private string titleFilter = string.Empty;

    private IQueryable<Movie> FilteredMovies =>
        context.Movie.Where(m => m.Title!.Contains(titleFilter));

    protected override void OnInitialized()
    {
        context = DbFactory.CreateDbContext();
    }

    public async ValueTask DisposeAsync() => await context.DisposeAsync();
}

在前面的代码中:

  • 系统将使用 @inject 指令。
  • 该服务在 OnInitialized 方法中解析,并分配给 context 变量。
  • context 服务创建 FilteredMovie 列表。

另一种从 DI 解析服务的方法是使用构造函数注入。 以下 Razor Pages 代码使用构造函数注入来从 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();
    }
}

在前面的代码中,IndexModel 构造函数采用类型为 RazorPagesMovieContext的参数,该参数在运行时解析为 _context 变量。 上下文对象用于在 OnGetAsync 方法中创建电影列表。

有关详细信息,请参阅 ASP.NET Core Blazor 依赖项注入ASP.NET Core 中的依赖项注入

Middleware

请求处理管道由一系列中间件组件组成。 每个组件在 HttpContext 上执行操作,调用管道中的下一个中间件或终止请求。

按照惯例,通过调用 Use{Feature} 扩展方法,向管道添加中间件组件。 以下代码演示了如何使用名为 Use{Feature} 的方法将中间件添加到应用:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MoviesContext") 
        ?? throw new InvalidOperationException("Connection string not found.")));

builder.Services.AddQuickGridEntityFrameworkAdapter();

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;

    SeedData.Initialize(services);
}

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    app.UseHsts();
    app.UseMigrationsEndPoint();
}
app.UseHttpsRedirection();

app.UseAntiforgery();

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

有关详细信息,请参阅 ASP.NET Core 中间件

Host

启动时,ASP.NET Core 应用将生成 主机。 主机封装应用的所有资源,例如:

  • HTTP 服务器实现
  • 中间件组件
  • Logging
  • 依赖关系注入 (DI) 服务
  • Configuration

有三个不同的主机能够运行 ASP.NET Core 应用:

建议使用 ASP.NET Core WebApplicationWebApplicationBuilder 类型,并在所有 ASP.NET 核心模板中使用。 WebApplication 的行为类似于 .NET 泛型主机,并公开许多相同的接口,但需要更少的回调进行配置。 ASP.NET Core WebHost 仅适用于后向兼容性。

以下示例实例化 WebApplication 并将其分配给名为 app的变量:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContextFactory<BlazorWebAppMoviesContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MoviesContext") 
        ?? throw new InvalidOperationException("Connection string not found.")));

builder.Services.AddQuickGridEntityFrameworkAdapter();

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

WebApplicationBuilder.Build 方法使用一组默认选项配置主机,例如:

  • Kestrel 用作 Web 服务器并启用 IIS 集成。
  • 、环境变量、命令行参数和其他配置源加载appsettings.json
  • 将日志记录输出发送到控制台并调试提供程序。

非网页场景

泛型主机允许其他类型的应用使用交叉框架扩展,例如日志记录、依赖项注入(DI)、配置和应用生存期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机ASP.NET Core 中使用托管服务的后台任务

Servers

ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器将请求作为由请求功能组成的一组传递给应用

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 服务器实现

Configuration

ASP.NET Core 提供了一个 配置 框架,该框架从一组有序的配置提供程序中获取名称-值对的设置。 可将内置配置提供程序用于各种源,例如 .json 文件、.xml 文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。

默认情况下,ASP.NET Core 应用程序被配置为从appsettings.json、环境变量、命令行等读取。 加载应用配置后,来自环境变量的值将替代来自 appsettings.json 的值。

为了管理机密配置数据(如开发环境中的密码),.NET 提供 机密管理器。 对于生产机密,建议使用 Azure 密钥保管库

有关详细信息,请参阅 ASP.NET Core 中的配置

Environments

执行环境(例如 DevelopmentStagingProduction)在 ASP.NET Core 中可用。 通过设置 ASPNETCORE_ENVIRONMENT 环境变量来指定应用的运行环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment 实现中。 通过依赖关系注入 (DI),可以在应用中任何位置实现此操作。

以下示例未在 环境中运行时配置异常处理程序和 HTTP 严格传输安全协议 (HSTS) 中间件:

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    app.UseHsts();
    app.UseMigrationsEndPoint();
}

有关详细信息,请参阅 ASP.NET 核心运行时环境

Logging

ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:

  • Console
  • Debug
  • Windows 事件跟踪
  • Windows 事件日志
  • TraceSource
  • Azure App 服务
  • Azure Application Insights

若要创建服务,请从依赖关系注入 (DI) 解析 ILogger<TCategoryName> 服务,并调用 LogInformation 等日志记录方法。 以下示例演示了如何在 .razor 中的页面的 Blazor Web App 文件中获取和使用记录器。 当在 CreateBuilder中调用 Program.cs 方法时,记录器对象和控制台提供程序会自动存储在 DI 容器中。

@page "/weather"
@attribute [StreamRendering]
@inject ILogger<Weather> Logger

<PageTitle>Weather</PageTitle>

<h1>Weather</h1>

<p>This component demonstrates showing data and logging.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th aria-label="Temperature in Celsius">Temp. (C)</th>
                <th aria-label="Temperature in Fahrenheit">Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        // Simulate asynchronous loading to demonstrate streaming rendering
       
        await Task.Delay(500);

        Logger.LogInformation("This is an information log message.");
        Logger.LogWarning("This is a warning log message.");
        Logger.LogError("This is an error log message.");

        var startDate = DateOnly.FromDateTime(DateTime.Now);
        var summaries = new[] { "Freezing", "Bracing", "Chilly",
            "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
        forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = startDate.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = summaries[Random.Shared.Next(summaries.Length)]
        }).ToArray();
    }

    private class WeatherForecast
    {
        public DateOnly Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}

有关详细信息,请参阅 .NET 中的日志记录和 ASP.NET Core

Routing

ASP.NET Core 中的路由是一种将传入请求映射到应用程序中特定终结点的机制。 它使你能够定义对应于不同组件的 URL 模式,例如 Blazor 组件、Razor 页、MVC 控制器操作或中间件。

UseRouting(IApplicationBuilder) 方法将路由中间件添加到请求管道。 此中间件处理路由信息并确定每个请求的相应终结点。 除非要更改中间件的处理顺序,否则无需显式调用 UseRouting

有关详细信息,请参阅 ASP.NET Core 中的路由ASP.NET Core Blazor 路由和导航

错误处理

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)
  • Web 根,通常是wwwroot文件夹。

在开发中,内容根目录默认为项目的根目录。 此目录也是应用内容文件和 Web 根目录的基本路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅“内容根”

网站根目录

Web 根目录是公用静态资源文件的基路径,例如:

  • 样式表 (.css)
  • JavaScript (.js
  • 图像(.png.jpg

默认情况下,静态文件仅从 Web 根目录及其子目录提供。 Web 根路径默认为 {CONTENT ROOT}/wwwroot,其中 {CONTENT ROOT} 占位符为内容根目录。 在构建主机时设置路径,可指定不同的 Web 根目录。 有关详细信息,请参阅 Web 根

防止使用项目文件中的 wwwroot<Content> 中发布文件。 以下示例阻止在 wwwroot/local 及其子目录中发布内容:

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

在 Razor.cshtml 文件中,~/ 指向 Web 根。 以~/虚拟路径开头的路径称为虚拟路径

有关详细信息,请参阅 ASP.NET Core 中的静态文件

如何下载示例

很多文章和教程中都包含有示例代码链接。

  1. 下载 ASP.NET 存储库 zip 文件
  2. 解压缩 AspNetCore.Docs-main.zip 文件。
  3. 若要在解压缩的存储库中访问文章的示例应用,请借助文章的示例链接中的 URL 来导航到示例文件夹。 通常,文章的示例链接显示在文章顶部,链接文本为“查看或下载示例代码”。

示例代码中的预处理器指令

为了演示多个方案,示例应用使用 #define#if-#else/#elif-#endif 预处理器指令选择性地编译和运行示例代码中不同的片段。 对于那些利用此方法的示例,请将 C# 文件顶部的 #define 指令设置为定义与你想要运行的方案相关联的符号。 一些示例要求在多个文件的顶部定义符号才能运行方案。

例如,以下 #define 符号列表指示四个方案可用(每个符号一个方案)。 当前示例配置运行 TemplateCode 方案:

#define TemplateCode // or LogFromMain or ExpandDefault or FilterInCode

若要更改示例以运行 ExpandDefault 方案,请定义 ExpandDefault 符号并保留剩余的符号处于被注释掉的状态:

#define ExpandDefault // TemplateCode or LogFromMain or FilterInCode

若要详细了解如何使用 C# 预处理器指令选择性地编译代码段,请参阅 #define(C# 参考)#if(C# 参考)

示例代码中的区域

一些示例应用包含 #region#endregion C# 指令包围的代码部分。 文档生成系统将这些区域注入到呈现的文档主题中。

区域名称通常包含“代码段”一词。以下示例显示了名为 snippet_WebHostDefaults 的区域:

#region snippet_WebHostDefaults
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    });
#endregion

前面的 C# 代码片段在主题的 markdown 文件中使用以下行引用:

[!code-csharp[](sample/SampleApp/Program.cs?name=snippet_WebHostDefaults)]

可以安全地忽略或删除围绕代码的 #region#endregion 指令。 如果打算运行本主题中所述的示例方案,请不要更改这些指令中的代码。

有关详细信息,请参阅 参与 ASP.NET 文档:代码片段

其他资源

ASP.NET 核心 Blazor 基础知识

本文概述了生成 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.Servicesbuilder.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();
    }
}

Middleware

请求处理管道由一系列中间件组件组成。 每个组件在 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 中间件

Host

启动时,ASP.NET Core 应用将生成 主机。 主机封装应用的所有资源,例如:

  • HTTP 服务器实现
  • 中间件组件
  • Logging
  • 依赖关系注入 (DI) 服务
  • Configuration

有三个不同的主机能够运行 ASP.NET Core 应用:

建议在所有 ASP.NET Core 模板中使用 ASP.NET Core WebApplicationWebApplicationBuilder 类型。 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 方法使用一组默认选项配置主机,例如:

  • Kestrel 用作 Web 服务器并启用 IIS 集成。
  • 、环境变量、命令行参数和其他配置源加载appsettings.json
  • 将日志记录输出发送到控制台并调试提供程序。

非 Web 场景

其他类型的应用可通过通用主机使用横切框架扩展,例如日志记录、依赖项注入 (DI)、配置和应用生命周期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机ASP.NET Core 中使用托管服务的后台任务

Servers

ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器将请求作为由请求功能组成的一组传递给应用

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 服务器实现

Configuration

ASP.NET Core 提供了一个 配置 框架,该框架从一组有序的配置提供程序中获取名称-值对的设置。 可将内置配置提供程序用于各种源,例如 .json 文件、.xml 文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。

默认情况下,ASP.NET Core 应用程序被配置为从appsettings.json、环境变量、命令行等读取。 加载应用配置后,来自环境变量的值将替代来自 appsettings.json 的值。

为了管理机密配置数据(如密码),.NET 提供 机密管理器。 对于生产机密,建议使用 Azure 密钥保管库

有关详细信息,请参阅 ASP.NET Core 中的配置

Environments

执行环境(例如 DevelopmentStagingProduction)在 ASP.NET Core 中可用。 通过设置 ASPNETCORE_ENVIRONMENT 环境变量来指定应用的运行环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment 实现中。 通过依赖关系注入 (DI),可以在应用中任何位置实现此操作。

以下示例未在 环境中运行时配置异常处理程序和 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 核心运行时环境

Logging

ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:

  • Console
  • Debug
  • Windows 事件跟踪
  • Windows 事件日志
  • TraceSource
  • Azure App 服务
  • 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 中的日志记录和 ASP.NET Core

Routing

路由是映射到处理器的 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)
  • Web 根,通常是 wwwroot 文件夹。

在开发中,内容根目录默认为项目的根目录。 此目录也是应用内容文件和 Web 根目录的基本路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅“内容根”

Web 根

Web 根目录是公用静态资源文件的基路径,例如:

  • 样式表 (.css)
  • JavaScript (.js
  • 图像(.png.jpg

默认情况下,静态文件仅从 Web 根目录及其子目录提供。 Web 根路径默认为 {content root}/wwwroot。 在构建主机时设置路径,可指定不同的 Web 根目录。 有关详细信息,请参阅 Web 根

禁止在 wwwroot 中通过项目文件中的 Content 项目项发布文件。 以下示例阻止在 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 中的依赖项注入

Middleware

请求处理管道由一系列中间件组件组成。 每个组件在 HttpContext 上执行操作,调用管道中的下一个中间件或终止请求。

按照惯例,通过在 Use... 方法中调用 Startup.Configure 扩展方法,向管道添加中间件组件。 例如,要启用静态文件的呈现,请调用 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 中间件

Host

启动时,ASP.NET Core 应用将生成 主机。 主机封装应用的所有资源,例如:

  • HTTP 服务器实现
  • 中间件组件
  • Logging
  • 依赖关系注入 (DI) 服务
  • Configuration

有两个不同的主机:

  • .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>();
            });
}

CreateDefaultBuilderConfigureWebHostDefaults 方法为主机配置一组默认选项,例如:

  • Kestrel 用作 Web 服务器并启用 IIS 集成。
  • appsettings.jsonappsettings.{Environment}.json、环境变量、命令行参数和其他配置源中加载配置。
  • 将日志记录输出发送到控制台并调试提供程序。

有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机

非网页场景

其他类型的应用可通过通用主机使用横切框架扩展,例如日志记录、依赖项注入 (DI)、配置和应用生命周期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机ASP.NET Core 中使用托管服务的后台任务

Servers

ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器将请求作为由请求功能组成的一组传递给应用

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 服务器实现

Configuration

ASP.NET Core 提供了配置框架,可以从配置提供程序的有序集中将设置作为名称/值对。 可将内置配置提供程序用于各种源,例如 .json 文件、.xml 文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。

默认情况下,ASP.NET Core 应用程序被配置为从appsettings.json、环境变量、命令行等读取。 加载应用配置后,来自环境变量的值将替代来自 appsettings.json 的值。

读取相关配置值的首选方法是使用选项模式。 有关详细信息,请参阅使用选项模式绑定分层配置数据

为了管理机密配置数据(如密码),.NET 提供 机密管理器。 对于生产机密,建议使用 Azure 密钥保管库

有关详细信息,请参阅 ASP.NET Core 中的配置

Environments

执行环境(例如 DevelopmentStagingProduction)是 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 核心运行时环境

Logging

ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:

  • Console
  • Debug
  • Windows 事件跟踪
  • Windows 事件日志
  • TraceSource
  • Azure App 服务
  • 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 中的日志记录和 ASP.NET Core

Routing

路由是映射到处理器的 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)
  • Web 根,通常是 wwwroot 文件夹。

在开发中,内容根目录默认为项目的根目录。 此目录也是应用内容文件和 Web 根目录的基本路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅“内容根”

网站根目录

Web 根目录是公用静态资源文件的基路径,例如:

  • 样式表 (.css)
  • JavaScript (.js
  • 图像(.png.jpg

默认情况下,静态文件仅从 Web 根目录及其子目录提供。 Web 根路径默认为 {content root}/wwwroot。 在构建主机时设置路径,可指定不同的 Web 根目录。 有关详细信息,请参阅 Web 根

禁止在 wwwroot 中通过项目文件中的 Content 项目项发布文件。 以下示例阻止在 wwwroot/local 及其子目录中发布内容:

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

在 Razor.cshtml 文件中,波形符-斜线 (~/) 指向 Web 根。 以~/虚拟路径开头的路径称为虚拟路径

有关详细信息,请参阅 ASP.NET Core 中的静态文件

如何下载示例

很多文章和教程中都包含有示例代码链接。

  1. 下载 ASP.NET 存储库 zip 文件
  2. 解压缩 AspNetCore.Docs-main.zip 文件。
  3. 若要在解压缩的存储库中访问文章的示例应用,请借助文章的示例链接中的 URL 来导航到示例文件夹。 通常,文章的示例链接显示在文章顶部,链接文本为“查看或下载示例代码”。

示例代码中的预处理器指令

为了演示多个方案,示例应用使用 #define#if-#else/#elif-#endif 预处理器指令选择性地编译和运行示例代码中不同的片段。 对于那些利用此方法的示例,请将 C# 文件顶部的 #define 指令设置为定义与你想要运行的方案相关联的符号。 一些示例要求在多个文件的顶部定义符号才能运行方案。

例如,以下 #define 符号列表指示四个方案可用(每个符号一个方案)。 当前示例配置运行 TemplateCode 方案:

#define TemplateCode // or LogFromMain or ExpandDefault or FilterInCode

若要更改示例以运行 ExpandDefault 方案,请定义 ExpandDefault 符号并保留剩余的符号处于被注释掉的状态:

#define ExpandDefault // TemplateCode or LogFromMain or FilterInCode

若要详细了解如何使用 C# 预处理器指令选择性地编译代码段,请参阅 #define(C# 参考)#if(C# 参考)

示例代码中的区域

一些示例应用包含 #region#endregion C# 指令包围的代码部分。 文档生成系统将这些区域注入到呈现的文档主题中。

区域名称通常包含“代码段”一词。以下示例显示了名为 snippet_WebHostDefaults 的区域:

#region snippet_WebHostDefaults
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    });
#endregion

前面的 C# 代码片段在主题的 markdown 文件中使用以下行引用:

[!code-csharp[](sample/SampleApp/Program.cs?name=snippet_WebHostDefaults)]

可以安全地忽略或删除围绕代码的 #region#endregion 指令。 如果打算运行本主题中所述的示例方案,请不要更改这些指令中的代码。

有关详细信息,请参阅 参与 ASP.NET 文档:代码片段

本文概述了生成 ASP.NET Core 应用的基础知识,包括依赖关系注入 (DI)、配置、中间件等等。

有关添加或取代本文中指导的 Blazor 基本指导,请参阅 ASP.NET Core Blazor 基础知识

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.Servicesbuilder.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();
    }
}

Middleware

请求处理管道由一系列中间件组件组成。 每个组件在 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 中间件

Host

启动时,ASP.NET Core 应用将生成 主机。 主机封装应用的所有资源,例如:

  • HTTP 服务器实现
  • 中间件组件
  • Logging
  • 依赖关系注入 (DI) 服务
  • Configuration

有三个不同的主机能够运行 ASP.NET Core 应用:

建议在所有 ASP.NET Core 模板中使用 ASP.NET Core WebApplicationWebApplicationBuilder 类型。 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 方法使用一组默认选项配置主机,例如:

  • Kestrel 用作 Web 服务器并启用 IIS 集成。
  • 、环境变量、命令行参数和其他配置源加载appsettings.json
  • 将日志记录输出发送到控制台并调试提供程序。

非web场景

其他类型的应用可通过通用主机使用横切框架扩展,例如日志记录、依赖项注入 (DI)、配置和应用生命周期管理。 有关详细信息,请参阅 ASP.NET Core 中的 .NET 通用主机ASP.NET Core 中使用托管服务的后台任务

Servers

ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器将请求作为由请求功能组成的一组传递给应用

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 服务器实现

Configuration

ASP.NET Core 提供了一个 配置 框架,该框架从一组有序的配置提供程序中获取名称-值对的设置。 可将内置配置提供程序用于各种源,例如 .json 文件、.xml 文件、环境变量和命令行参数。 可编写自定义配置提供程序以支持其他源。

默认情况下,ASP.NET Core 应用程序被配置为从appsettings.json、环境变量、命令行等读取。 加载应用配置后,来自环境变量的值将替代来自 appsettings.json 的值。

为了管理机密配置数据(如密码),.NET 提供 机密管理器。 对于生产机密,建议使用 Azure 密钥保管库

有关详细信息,请参阅 ASP.NET Core 中的配置

Environments

执行环境(例如 DevelopmentStagingProduction)在 ASP.NET Core 中可用。 通过设置 ASPNETCORE_ENVIRONMENT 环境变量来指定应用的运行环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IWebHostEnvironment 实现中。 通过依赖关系注入 (DI),可以在应用中任何位置实现此操作。

以下示例未在 环境中运行时配置异常处理程序和 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 核心运行时环境

Logging

ASP.NET Core 支持适用于各种内置和第三方日志记录提供程序的日志记录 API。 可用的提供程序包括:

  • Console
  • Debug
  • Windows 事件跟踪
  • Windows 事件日志
  • TraceSource
  • Azure App 服务
  • 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 中的日志记录和 ASP.NET Core

Routing

路由是映射到处理器的 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)
  • Web 根,通常是 wwwroot 文件夹。

在开发中,内容根目录默认为项目的根目录。 此目录也是应用内容文件和 Web 根目录的基本路径。 在构建主机时设置路径,可指定不同的内容根目录。 有关详细信息,请参阅“内容根”

网站根目录

Web 根目录是公用静态资源文件的基路径,例如:

  • 样式表 (.css)
  • JavaScript (.js
  • 图像(.png.jpg

默认情况下,静态文件仅从 Web 根目录及其子目录提供。 Web 根路径默认为 {content root}/wwwroot。 在构建主机时设置路径,可指定不同的 Web 根目录。 有关详细信息,请参阅 Web 根

禁止在 wwwroot 中通过项目文件中的 Content 项目项发布文件。 以下示例阻止在 wwwroot/local 及其子目录中发布内容:

<ItemGroup>
  <Content Update="wwwroot\local\**\*.*" CopyToPublishDirectory="Never" />
</ItemGroup>

在 Razor.cshtml 文件中,~/ 指向 Web 根。 以~/虚拟路径开头的路径称为虚拟路径

有关详细信息,请参阅 ASP.NET Core 中的静态文件

如何下载示例

很多文章和教程中都包含有示例代码链接。

  1. 下载 ASP.NET 存储库 zip 文件
  2. 解压缩 AspNetCore.Docs-main.zip 文件。
  3. 若要在解压缩的存储库中访问文章的示例应用,请借助文章的示例链接中的 URL 来导航到示例文件夹。 通常,文章的示例链接显示在文章顶部,链接文本为“查看或下载示例代码”。

示例代码中的预处理器指令

为了演示多个方案,示例应用使用 #define#if-#else/#elif-#endif 预处理器指令选择性地编译和运行示例代码中不同的片段。 对于那些利用此方法的示例,请将 C# 文件顶部的 #define 指令设置为定义与你想要运行的方案相关联的符号。 一些示例要求在多个文件的顶部定义符号才能运行方案。

例如,以下 #define 符号列表指示四个方案可用(每个符号一个方案)。 当前示例配置运行 TemplateCode 方案:

#define TemplateCode // or LogFromMain or ExpandDefault or FilterInCode

若要更改示例以运行 ExpandDefault 方案,请定义 ExpandDefault 符号并保留剩余的符号处于被注释掉的状态:

#define ExpandDefault // TemplateCode or LogFromMain or FilterInCode

若要详细了解如何使用 C# 预处理器指令选择性地编译代码段,请参阅 #define(C# 参考)#if(C# 参考)

示例代码中的区域

一些示例应用包含 #region#endregion C# 指令包围的代码部分。 文档生成系统将这些区域注入到呈现的文档主题中。

区域名称通常包含“代码段”一词。以下示例显示了名为 snippet_WebHostDefaults 的区域:

#region snippet_WebHostDefaults
Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    });
#endregion

前面的 C# 代码片段在主题的 markdown 文件中使用以下行引用:

[!code-csharp[](sample/SampleApp/Program.cs?name=snippet_WebHostDefaults)]

可以安全地忽略或删除围绕代码的 #region#endregion 指令。 如果打算运行本主题中所述的示例方案,请不要更改这些指令中的代码。

有关详细信息,请参阅 参与 ASP.NET 文档:代码片段