概述

ASP.NET Core 基础知识

本文概述了了解如何开发 ASP.NET Core 应用的关键主题。

Startup 类

Startup 类位于:

  • 已配置应用所需的服务。
  • 已定义请求处理管道。

服务是应用使用的组件 。 例如,日志记录组件就是一项服务。 将配置(或注册)服务的代码添加到 Startup.ConfigureServices 方法中 。

请求处理管道由一系列中间件组件组成 。 例如,中间件可能处理对静态文件的请求或将 HTTP 请求重定向到 HTTPS。 每个中间件在 HttpContext 上执行异步操作,然后调用管道中的下一个中间件或终止请求。 将配置请求处理管道的代码添加到 Startup.Configure 方法中。

下面是 Startup 类示例:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        services.AddDbContext<MovieContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("MovieDb")));
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseMvc();
    }
}

有关详细信息,请参阅 ASP.NET Core 中的应用启动

依赖关系注入(服务)

ASP.NET Core 有内置的依赖关系注入 (DI) 框架,可使配置的服务适用于应用的类。 在类中获取服务实例的一种方法是使用所需类型的参数创建构造函数。 参数可以是服务类型或接口。 DI 系统在运行时提供服务。

下面是使用 DI 获取 Entity Framework Core 上下文对象的类。 突出显示的行是构造函数注入的示例:

public class IndexModel : PageModel
{
    private readonly RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovieContext context)
    {
        _context = context;
    }
    // ...
    public async Task OnGetAsync()
    {
        var movies = from m in _context.Movies
                        select m;
        Movies = await movies.ToListAsync();
    }
}

虽然 DI 是内置的,但旨在允许插入第三方控制反转 (IoC) 容器(根据需要)。

有关详细信息,请参阅 在 ASP.NET Core 依赖注入

中间件

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

按照惯例,通过在 Startup.Configure 方法中调用其 Use... 扩展方法,向管道添加中间件组件。 例如,要启用静态文件的呈现,请调用 UseStaticFiles

以下示例中突出显示的代码配置请求处理管道:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        services.AddDbContext<MovieContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("MovieDb")));
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseMvc();
    }
}

ASP.NET Core 包含一组丰富的内置中间件,并且你也可以编写自定义中间件。

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

主机

ASP.NET Core 应用在启动时构建主机 。 主机是封装所有应用资源的对象,例如:

  • HTTP 服务器实现
  • 中间件组件
  • Logging
  • DI
  • 配置

一个对象中包含所有应用的相互依赖资源的主要原因是生存期管理:控制应用启动和正常关闭。

提供两个主机:通用主机和 Web 主机。 通用主机是推荐的机型,而 Web 主机仅很适用于向后兼容。

要创建主机的代码位于 Program.Main 中:

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.json、appsettings.[EnvironmentName].json、环境变量、命令行参数和其他配置源中加载配置 。
  • 将日志记录输出发送到控制台并调试提供程序。

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

提供两个主机:Web 主机和通用主机。 在 ASP.NET Core 2.x 上,通用主机仅用于非 Web 方案。

要创建主机的代码位于 Program.Main 中:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

CreateDefaultBuilder 方法配置具有常用选项的主机,如下所示:

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

有关详细信息,请参阅 ASP.NET Core Web 主机

非 Web 方案

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

服务器

ASP.NET Core 应用使用 HTTP 服务器实现侦听 HTTP 请求。 服务器对应用的请求在表面上呈现为一组由 HttpContext 组成的请求功能

有关详细信息,请参阅 ASP.NET Core 中的 Web 服务器实现

配置

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

例如,可以指定配置来自 appsettings.json 和环境变量 。 然后,当请求 ConnectionString 的值时,框架首先在 appsettings.json 文件中查找 。 如果也在环境变量中找到了值,那么来自环境变量的值将优先使用。

为了管理密码等机密配置数据,ASP.NET Core 提供了机密管理器工具 对于生产机密,建议使用 Azure 密钥保管库

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

选项

在可能的情况下,ASP.NET Core 按照选项模式来存储和检索配置值 。 选项模式使用类来表示相关设置的组。

例如,以下代码可以设置 WebSocket 选项:

var options = new WebSocketOptions  
{  
   KeepAliveInterval = TimeSpan.FromSeconds(120),  
   ReceiveBufferSize = 4096
};  
app.UseWebSockets(options);

有关详细信息,请参阅 ASP.NET Core 中的选项模式

环境

执行环境(例如“开发”、“暂存”和“生产”)是 ASP.NET Core 中的高级概念 。 可以通过设置 ASPNETCORE_ENVIRONMENT 环境变量来指定运行应用的环境。 ASP.NET Core 在应用启动时读取该环境变量,并将该值存储在 IHostingEnvironment 实现中。 可通过 DI 在应用的任何位置使用环境对象。

以下来自 Startup 类的示例代码将应用配置为仅在开发过程中运行时提供详细的错误信息:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseMvc();
}

有关详细信息,请参阅 在 ASP.NET Core 中使用多个环境

Logging

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

  • 控制台
  • 调试
  • Windows 事件跟踪
  • Windows 事件日志
  • TraceSource
  • Azure 应用服务
  • Azure Application Insights

通过从 DI 获取 ILogger 对象并调用日志方法,从应用代码中的任何位置写入日志。

下面是使用 ILogger 对象的示例代码,其中突出显示了构造函数注入和日志记录方法调用。

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;
    }
}

通过 ILogger 接口,可将任意数量的字段传递给日志提供程序。 字段通常用于构造消息字符串,但提供程序还可将其作为单独的字段发送到数据存储。 此功能使日志提供程序可以实现语义日志记录,也称为结构化日志记录

有关详细信息,请参阅 .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 集成,这是用于瞬时故障处理的常用第三方库 。
  • 管理基础 HttpClientMessageHandler 实例的池和生存期,避免在手动管理 HttpClient 生存期时出现常见的 DNS 问题。
  • (通过 ILogger)添加可配置的记录体验,以处理工厂创建的客户端发送的所有请求。

有关详细信息,请参阅 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求

内容根

内容根是指向以下内容的基本路径:

  • 托管应用程序的可执行文件 (.exe )。
  • 构成应用程序的已编译程序集 (.dll )。
  • 应用使用的非代码内容文件,例如:
    • Razor 文件(.cshtml 、.razor )
    • 配置文件(.json 、.xml )
    • 数据文件 (.db )
  • Web 根目录,通常是已发布的 wwwroot 文件夹。

在开发过程中:

  • 内容根默认为项目的根目录。
  • 项目的根目录用于创建:
    • 项目根目录中应用的非代码内容文件的路径。
    • Web 根目录,通常是项目根目录中的 wwwroot 文件夹。

构建主机时,可以指定备用内容根路径。 有关详细信息,请参阅 .NET 通用主机

构建主机时,可以指定备用内容根路径。 有关详细信息,请参阅 ASP.NET Core Web 主机

Web 根

Web 根目录是公共、非代码、静态资源文件的基本路径,例如:

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

默认情况下,静态文件仅从 Web 根目录(及子目录)提供。

Web 根路径默认为 {content root}/wwwroot ,但构建主机时可以指定其他 Web 根路径。 有关详细信息,请参阅 .NET 通用主机

Web 根路径默认为 {content root}/wwwroot ,但构建主机时可以指定其他 Web 根路径。 有关详细信息,请参阅 Web 根目录

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

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

要阻止将静态标识资产发布到 Web 根目录,请参阅 ASP.NET Core 上的标识简介

在 Razor (.cshtml ) 文件中,波浪号斜杠 (~/) 指向 Web 根目录。 ~/ 开头的路径称为虚拟路径 。

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