从 ASP.NET Core 2.2 迁移到3。0Migrate from ASP.NET Core 2.2 to 3.0

作者: Scott AddieRick AndersonBy Scott Addie and Rick Anderson

本文介绍如何将现有 ASP.NET Core 2.2 项目更新为 ASP.NET Core 3.0。This article explains how to update an existing ASP.NET Core 2.2 project to ASP.NET Core 3.0.

PrerequisitesPrerequisites

在 global.json 中更新 .NET Core SDK 版本Update .NET Core SDK version in global.json

如果解决方案依赖于全局 json文件来面向特定的 .NET Core SDK 版本,请将其 version 属性更新为安装在计算机上的3.0 版本:If your solution relies upon a global.json file to target a specific .NET Core SDK version, update its version property to the 3.0 version installed on your machine:

{
  "sdk": {
    "version": "3.0.100"
  }
}

更新项目文件Update the project file

更新目标框架Update the Target Framework

ASP.NET Core 3.0 及更高版本仅在 .NET Core 上运行。ASP.NET Core 3.0 and later only run on .NET Core. 目标框架名字对象(TFM)设置为 netcoreapp3.0Set the Target Framework Moniker (TFM) to netcoreapp3.0:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

删除过时的包引用Remove obsolete package references

ASP.NET Core 不再产生大量 NuGet 包功能。ASP.NET Core no longer produces a large number of NuGet packages features. 这些包引用应从项目文件中删除。These package references should be removed from your project file. 例如,模板生成的 ASP.NET Core 2.2 web 应用的项目文件:For example, the template-generated project file for an ASP.NET Core 2.2 web app:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

更新的 ASP.NET Core 3.0 项目文件:The updated ASP.NET Core 3.0 project file:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

更新的 ASP.NET Core 3.0 项目文件:The updated ASP.NET Core 3.0 project file:

  • <PropertyGroup>In the <PropertyGroup>:

    • 将 TFM 更新为 netcoreapp3.0Updates the TFM to netcoreapp3.0
    • 删除 <AspNetCoreHostingModel> 元素。Removes the <AspNetCoreHostingModel> element. 有关详细信息,请参阅本文档中的进程内承载模型For more information, see In-process hosting model in this document.
  • <ItemGroup>In the <ItemGroup>:

    • 删除 Microsoft.AspNetCore.AppMicrosoft.AspNetCore.App is removed. 有关详细信息,请参阅本文档中的框架参考For more information, see Framework reference in this document.
    • 将删除 Microsoft.AspNetCore.Razor.Design,并且不会再生成下面的包列表。Microsoft.AspNetCore.Razor.Design is removed and in the following list of packages no longer being produced.

若要查看不再生成的包的完整列表,请选择以下展开列表:To see the full list of packages that are no longer produced, select the following expand list:

单击此处展开不再生成的包列表Click here to expand the list of packages no longer being produced
  • Microsoft.AspNetCoreMicrosoft.AspNetCore
  • Microsoft.AspNetCore.AllMicrosoft.AspNetCore.All
  • Microsoft.AspNetCore.AppMicrosoft.AspNetCore.App
  • Microsoft.AspNetCore.AntiforgeryMicrosoft.AspNetCore.Antiforgery
  • Microsoft.AspNetCore.AuthenticationMicrosoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.AbstractionsMicrosoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication.CookiesMicrosoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.CoreMicrosoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.JwtBearerMicrosoft.AspNetCore.Authentication.JwtBearer
  • Microsoft.AspNetCore.Authentication.OAuthMicrosoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authentication.OpenIdConnectMicrosoft.AspNetCore.Authentication.OpenIdConnect
  • Microsoft.AspNetCore.AuthorizationMicrosoft.AspNetCore.Authorization
  • Microsoft.AspNetCore.Authorization.PolicyMicrosoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore.CookiePolicyMicrosoft.AspNetCore.CookiePolicy
  • Microsoft.AspNetCore.CorsMicrosoft.AspNetCore.Cors
  • Microsoft.AspNetCore.Cryptography.InternalMicrosoft.AspNetCore.Cryptography.Internal
  • Microsoft.AspNetCore.Cryptography.KeyDerivationMicrosoft.AspNetCore.Cryptography.KeyDerivation
  • Microsoft.AspNetCore.DataProtectionMicrosoft.AspNetCore.DataProtection
  • Microsoft.AspNetCore.DataProtection.AbstractionsMicrosoft.AspNetCore.DataProtection.Abstractions
  • Microsoft.AspNetCore.DataProtection.ExtensionsMicrosoft.AspNetCore.DataProtection.Extensions
  • Microsoft.AspNetCore.DiagnosticsMicrosoft.AspNetCore.Diagnostics
  • Microsoft.AspNetCore.Diagnostics.HealthChecksMicrosoft.AspNetCore.Diagnostics.HealthChecks
  • Microsoft.AspNetCore.HostFilteringMicrosoft.AspNetCore.HostFiltering
  • Microsoft.AspNetCore.HostingMicrosoft.AspNetCore.Hosting
  • Microsoft.AspNetCore.Hosting.AbstractionsMicrosoft.AspNetCore.Hosting.Abstractions
  • Microsoft.AspNetCore.Hosting.Server.AbstractionsMicrosoft.AspNetCore.Hosting.Server.Abstractions
  • Microsoft.AspNetCore.HttpMicrosoft.AspNetCore.Http
  • Microsoft.AspNetCore.Http.AbstractionsMicrosoft.AspNetCore.Http.Abstractions
  • Microsoft.AspNetCore.Http.ConnectionsMicrosoft.AspNetCore.Http.Connections
  • Microsoft.AspNetCore.Http.ExtensionsMicrosoft.AspNetCore.Http.Extensions
  • Microsoft.AspNetCore.Http.FeaturesMicrosoft.AspNetCore.Http.Features
  • Microsoft.AspNetCore.HttpOverridesMicrosoft.AspNetCore.HttpOverrides
  • Microsoft.AspNetCore.HttpsPolicyMicrosoft.AspNetCore.HttpsPolicy
  • Microsoft.AspNetCore.IdentityMicrosoft.AspNetCore.Identity
  • Microsoft.AspNetCore.LocalizationMicrosoft.AspNetCore.Localization
  • Microsoft.AspNetCore.Localization.RoutingMicrosoft.AspNetCore.Localization.Routing
  • Microsoft.AspNetCore.MiddlewareAnalysisMicrosoft.AspNetCore.MiddlewareAnalysis
  • Microsoft.AspNetCore.MvcMicrosoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.Mvc.AbstractionsMicrosoft.AspNetCore.Mvc.Abstractions
  • Microsoft.AspNetCore.Mvc.AnalyzersMicrosoft.AspNetCore.Mvc.Analyzers
  • Microsoft.AspNetCore.Mvc.ApiExplorerMicrosoft.AspNetCore.Mvc.ApiExplorer
  • Microsoft.AspNetCore.Mvc.Api.AnalyzersMicrosoft.AspNetCore.Mvc.Api.Analyzers
  • Microsoft.AspNetCore.Mvc.CoreMicrosoft.AspNetCore.Mvc.Core
  • Microsoft.AspNetCore.Mvc.CorsMicrosoft.AspNetCore.Mvc.Cors
  • Microsoft.AspNetCore.Mvc.DataAnnotationsMicrosoft.AspNetCore.Mvc.DataAnnotations
  • Microsoft.AspNetCore.Mvc.Formatters.JsonMicrosoft.AspNetCore.Mvc.Formatters.Json
  • Microsoft.AspNetCore.Mvc.Formatters.XmlMicrosoft.AspNetCore.Mvc.Formatters.Xml
  • Microsoft.AspNetCore.Mvc.LocalizationMicrosoft.AspNetCore.Mvc.Localization
  • Microsoft.AspNetCore.Mvc.RazorMicrosoft.AspNetCore.Mvc.Razor
  • Microsoft.AspNetCore.Mvc.Razor.ExtensionsMicrosoft.AspNetCore.Mvc.Razor.Extensions
  • Microsoft.AspNetCore.Mvc.Razor.ViewCompilationMicrosoft.AspNetCore.Mvc.Razor.ViewCompilation
  • Microsoft.AspNetCore.Mvc.RazorPagesMicrosoft.AspNetCore.Mvc.RazorPages
  • Microsoft.AspNetCore.Mvc.TagHelpersMicrosoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.ViewFeaturesMicrosoft.AspNetCore.Mvc.ViewFeatures
  • Microsoft.AspNetCore.RazorMicrosoft.AspNetCore.Razor
  • Microsoft.AspNetCore.Razor.RuntimeMicrosoft.AspNetCore.Razor.Runtime
  • Microsoft.AspNetCore.Razor.DesignMicrosoft.AspNetCore.Razor.Design
  • Microsoft.AspNetCore.ResponseCachingMicrosoft.AspNetCore.ResponseCaching
  • Microsoft.AspNetCore.ResponseCaching.AbstractionsMicrosoft.AspNetCore.ResponseCaching.Abstractions
  • Microsoft.AspNetCore.ResponseCompressionMicrosoft.AspNetCore.ResponseCompression
  • Microsoft.AspNetCore.RewriteMicrosoft.AspNetCore.Rewrite
  • Microsoft.AspNetCore.RoutingMicrosoft.AspNetCore.Routing
  • Microsoft.AspNetCore.Routing.AbstractionsMicrosoft.AspNetCore.Routing.Abstractions
  • Microsoft.AspNetCore.Server.HttpSysMicrosoft.AspNetCore.Server.HttpSys
  • Microsoft.AspNetCore.Server.IISMicrosoft.AspNetCore.Server.IIS
  • Microsoft.AspNetCore.Server.IISIntegrationMicrosoft.AspNetCore.Server.IISIntegration
  • Microsoft.AspNetCore.Server.KestrelMicrosoft.AspNetCore.Server.Kestrel
  • Microsoft.AspNetCore.Server.Kestrel.CoreMicrosoft.AspNetCore.Server.Kestrel.Core
  • Microsoft.AspNetCore.Server.Kestrel.HttpsMicrosoft.AspNetCore.Server.Kestrel.Https
  • Microsoft.AspNetCore.Server.Kestrel.Transport.AbstractionsMicrosoft.AspNetCore.Server.Kestrel.Transport.Abstractions
  • Microsoft.AspNetCore.Server.Kestrel.Transport.SocketsMicrosoft.AspNetCore.Server.Kestrel.Transport.Sockets
  • Microsoft.AspNetCore.SessionMicrosoft.AspNetCore.Session
  • Microsoft.AspNetCore.SignalRMicrosoft.AspNetCore.SignalR
  • Microsoft.AspNetCore.SignalR.CoreMicrosoft.AspNetCore.SignalR.Core
  • Microsoft.AspNetCore.StaticFilesMicrosoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSocketsMicrosoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilitiesMicrosoft.AspNetCore.WebUtilities
  • Microsoft.NetMicrosoft.Net.Http.Headers

查看重大更改Review breaking changes

查看重大更改Review breaking changes

框架引用Framework reference

通过上述某个包提供的 ASP.NET Core 功能可作为 Microsoft.AspNetCore.App 共享框架的一部分提供。Features of ASP.NET Core that were available through one of the packages listed above are available as part of the Microsoft.AspNetCore.App shared framework. 共享框架是计算机上安装的一组程序集( .dll文件),其中包含一个运行时组件和一个目标包。The shared framework is the set of assemblies (.dll files) that are installed on the machine and includes a runtime component, and a targeting pack. 有关详细信息,请参阅共享框架For more information, see The shared framework.

  • 面向 Microsoft.NET.Sdk.Web SDK 的项目隐式引用 Microsoft.AspNetCore.App 框架。Projects that target the Microsoft.NET.Sdk.Web SDK implicitly reference the Microsoft.AspNetCore.App framework.

对于这些项目,不需要其他引用:No additional references are required for these projects:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>
    ...
</Project>
  • 面向 Microsoft.NET.SdkMicrosoft.NET.Sdk.Razor SDK 的项目应将显式 FrameworkReference 添加到 Microsoft.AspNetCore.AppProjects that target Microsoft.NET.Sdk or Microsoft.NET.Sdk.Razor SDK, should add an explicit FrameworkReference to Microsoft.AspNetCore.App:
<Project Sdk="Microsoft.NET.Sdk.Razor">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
    ...
</Project>

使用 Docker 的依赖框架的生成Framework-dependent builds using Docker

使用依赖于 ASP.NET Core共享框架的包的、依赖于框架的控制台应用程序可能会给出以下运行时错误:Framework-dependent builds of console apps that use a package that depends on the ASP.NET Core shared framework may give the following runtime error:

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
  - No frameworks were found.

Microsoft.AspNetCore.App 是包含 ASP.NET Core 运行时的共享框架,只存在于dotnet/Core/aspnet docker 映像中。Microsoft.AspNetCore.App is the shared framework containing the ASP.NET Core runtime and is only present on the dotnet/core/aspnet docker image. 3.0 SDK 使用 asp.net core 减小框架依赖项的大小,方法是不包括共享框架中可用的库的重复副本。The 3.0 SDK reduces the size of framework dependent builds using asp.net core by not including duplicate copies of libraries that are available in the shared framework. 这可能会节省高达 18 MB,但要求 ASP.NET Core 运行时必须提供/安装才能运行应用。This is a potential savings of up to 18 MB but it requires that the ASP.NET Core runtime must be present / installed to run the app.

若要确定应用程序在 ASP.NET Core 共享框架上是否具有依赖关系(直接或间接),请检查应用程序生成/发布期间生成的runtimeconfig.template.json文件。To determine if the app has a dependency (either direct or indirect) on the ASP.NET Core shared framework, examine the runtimeconfig.json file generated during a build/publish of your app. 以下 JSON 文件显示了对 ASP.NET Core 共享框架的依赖项:The following JSON file shows a dependency on the ASP.NET Core shared framework:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "3.0.0"
    },
    "configProperties": {
      "System.GC.Server": true
    }
  }
}

如果你的应用使用的是 docker,请使用包含 ASP.NET Core 3.0 的基本映像。If your app is using docker, use a base image that includes ASP.NET Core 3.0. 例如 docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0For example, docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0.

添加已删除程序集的包引用Add package references for removed assemblies

ASP.NET Core 3.0 删除了之前属于 Microsoft.AspNetCore.App 包引用的某些程序集。ASP.NET Core 3.0 removes some assemblies that were previously part of the Microsoft.AspNetCore.App package reference. 若要继续使用这些程序集提供的功能,请参考相应包的3.0 版本:To continue using features provided by these assemblies, reference the 3.0 versions of the corresponding packages:

启动更改Startup changes

下图显示了 ASP.NET Core 2.2 Razor Pages Web 应用中已删除和已更改的行:The following image shows the deleted and changed lines in an ASP.NET Core 2.2 Razor Pages Web app:

ASP.NET Core 2.2 Razor Web 应用中的已删除和已更改的行

在上图中,删除的代码显示为红色。In the preceding image, deleted code is shown in red. 删除的代码不显示 cookie 选项代码,该代码在比较文件之前已被删除。The deleted code doesn't show cookie options code, which was deleted prior to comparing the files.

下图显示了 ASP.NET Core 3.0 Razor Pages Web 应用中添加和更改的行:The following image shows the added and changed lines in an ASP.NET Core 3.0 Razor Pages Web app:

ASP.NET Core 3.0 Razor Web 应用中添加和更改的行

在上图中,添加的代码显示为绿色。In the preceding image, added code is shown in green. 有关以下更改的信息:For information on the following changes:

分析器支持Analyzer support

目标为 Microsoft.NET.Sdk.Web 隐式引用分析器作为AspNetCore包的一部分交付的项目。Projects that target Microsoft.NET.Sdk.Web implicitly reference analyzers previously shipped as part of the Microsoft.AspNetCore.Mvc.Analyzers package. 不需要其他引用即可启用这些。No additional references are required to enable these.

如果你的应用使用以前使用AspNetCore包交付的API 分析器,则编辑项目文件以引用作为 .net Core Web SDK 的一部分提供的分析器:If your app uses API analyzers previously shipped using the Microsoft.AspNetCore.Mvc.Api.Analyzers package, edit your project file to reference the analyzers shipped as part of the .NET Core Web SDK:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
    </PropertyGroup>

    ...
</Project>

Razor 类库Razor Class Library

为 MVC 提供 UI 组件的 Razor 类库项目必须在项目文件中设置 AddRazorSupportForMvc 属性:Razor Class Library projects that provide UI components for MVC must set the AddRazorSupportForMvc property in the project file:

<PropertyGroup>
  <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>

进程内托管模型In-process hosting model

项目默认为 ASP.NET Core 3.0 或更高版本中的进程内承载模型Projects default to the in-process hosting model in ASP.NET Core 3.0 or later. 如果项目文件的值为 InProcess,则可以选择删除项目文件中的 <AspNetCoreHostingModel> 属性。You may optionally remove the <AspNetCoreHostingModel> property in the project file if its value is InProcess.

KestrelKestrel

配置Configuration

将 Kestrel 配置迁移到 ConfigureWebHostDefaultsProgram.cs)提供的 web 主机生成器:Migrate Kestrel configuration to the web host builder provided by ConfigureWebHostDefaults (Program.cs):

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

如果应用程序通过 HostBuilder 手动创建宿主,请在 ConfigureWebHostDefaults 的 web 主机生成器上调用 UseKestrelIf the app creates the host manually with HostBuilder, call UseKestrel on the web host builder in ConfigureWebHostDefaults:

public static void Main(string[] args)
{
    var host = new HostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
}

连接中间件替代连接适配器Connection Middleware replaces Connection Adapters

已从 Kestrel 中删除连接适配器(Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter)。Connection Adapters (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) have been removed from Kestrel. 将连接适配器替换为连接中间件。Replace Connection Adapters with Connection Middleware. 连接中间件与 ASP.NET Core 管道中的 HTTP 中间件类似,但对于较低级别的连接。Connection Middleware is similar to HTTP Middleware in the ASP.NET Core pipeline but for lower-level connections. HTTPS 和连接日志记录:HTTPS and connection logging:

  • 已从连接适配器移到连接中间件。Have been moved from Connection Adapters to Connection Middleware.
  • 这些扩展方法的工作方式与 ASP.NET Core 以前版本相同。These extension methods work as in previous versions of ASP.NET Core.

有关详细信息,请参阅Kestrel 文章的 ListenOptions 部分中的 TlsFilterConnectionHandler 示例For more information, see the TlsFilterConnectionHandler example in the ListenOptions.Protocols section of the Kestrel article.

已移动并公开传输抽象Transport abstractions moved and made public

Kestrel 传输层已作为 Connections.Abstractions 中的公共接口公开。The Kestrel transport layer has been exposed as a public interface in Connections.Abstractions. 作为这些更新的一部分:As part of these updates:

  • 已删除 Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions 和关联的类型。Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions and associated types have been removed.
  • NoDelay 已从 ListenOptions 转移到传输选项。NoDelay was moved from ListenOptions to the transport options.
  • 已从 KestrelServerOptions 中删除 Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingModeMicrosoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode was removed from KestrelServerOptions.

有关详细信息,请参阅以下 GitHub 资源:For more information, see the following GitHub resources:

Kestrel 请求尾端标头Kestrel Request trailer headers

对于面向 ASP.NET Core 早期版本的应用:For apps that target earlier versions of ASP.NET Core:

  • Kestrel 将 HTTP/1.1 分块尾端标头添加到请求标头集合。Kestrel adds HTTP/1.1 chunked trailer headers into the request headers collection.
  • 在将请求正文读取到末尾后,尾端可用。Trailers are available after the request body is read to the end.

这会导致一些有关标头和尾部的歧义的问题,因此,在3.0 中,已将尾端移至新集合(RequestTrailerExtensions)。This causes some concerns about ambiguity between headers and trailers, so the trailers have been moved to a new collection (RequestTrailerExtensions) in 3.0.

HTTP/2 请求尾端包括:HTTP/2 request trailers are:

  • ASP.NET Core 2.2 中不可用。Not available in ASP.NET Core 2.2.
  • 在3.0 中提供 RequestTrailerExtensionsAvailable in 3.0 as RequestTrailerExtensions.

提供了新的请求扩展方法来访问这些尾端。New request extension methods are present to access these trailers. 与 HTTP/1.1 一样,在请求正文读取到末尾后,尾端可用。As with HTTP/1.1, trailers are available after the request body is read to the end.

3.0 版本提供以下 RequestTrailerExtensions 方法:For the 3.0 release, the following RequestTrailerExtensions methods are available:

  • GetDeclaredTrailers – 获取请求 Trailer 标头,该标头将列出主体后预期的尾部。GetDeclaredTrailers – Gets the request Trailer header that lists which trailers to expect after the body.
  • SupportsTrailers – 指示请求是否支持接收尾端标头。SupportsTrailers – Indicates if the request supports receiving trailer headers.
  • CheckTrailersAvailable – 检查请求是否支持尾端以及是否可供读取。CheckTrailersAvailable – Checks if the request supports trailers and if they're available to be read. 此检查未假定有要读取的尾端。This check doesn't assume that there are trailers to read. 即使此方法返回 true,也没有要读取的尾端。There might be no trailers to read even if true is returned by this method.
  • GetTrailer – 获取响应中请求的尾随标头。GetTrailer – Gets the requested trailing header from the response. 请检查 SupportsTrailers,然后再调用 GetTrailer,如果请求不支持尾部标头,则可能出现 NotSupportedExceptionCheck SupportsTrailers before calling GetTrailer, or a NotSupportedException may occur if the request doesn't support trailing headers.

有关详细信息,请参阅将请求尾端置于单独的集合中(aspnet/AspNetCore #10410)For more information, see Put request trailers in a separate collection (aspnet/AspNetCore #10410).

已禁用 AllowSynchronousIOAllowSynchronousIO disabled

AllowSynchronousIO 启用或禁用同步 IO Api,如 HttpRequest.Body.ReadHttpResponse.Body.WriteStream.FlushAllowSynchronousIO enables or disables synchronous IO APIs, such as HttpRequest.Body.Read, HttpResponse.Body.Write, and Stream.Flush. 这些 Api 是线程不足的源,导致应用崩溃。These APIs are a source of thread starvation leading to app crashes. 在 3.0 中,默认情况下禁用 AllowSynchronousIOIn 3.0, AllowSynchronousIO is disabled by default. 有关详细信息,请参阅Kestrel 文章中的同步 IO 部分For more information, see the Synchronous IO section in the Kestrel article.

除了使用 ConfigureKestrel 的选项启用 AllowSynchronousIO 之外,还可以根据每个请求替代同步 IO,作为临时性的缓解措施:In addition to enabling AllowSynchronousIO with ConfigureKestrel's options, synchronous IO can also be overridden on a per-request basis as a temporary mitigation:

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();

if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

如果对在Dispose中调用同步 api 的 TextWriter 实现或其他流有问题,请改为调用新的 DisposeAsync API。If you have trouble with TextWriter implementations or other streams that call synchronous APIs in Dispose, call the new DisposeAsync API instead.

有关详细信息,请参阅[公告] AllowSynchronousIO 在所有服务器中禁用(aspnet/AspNetCore #7644)For more information, see [Announcement] AllowSynchronousIO disabled in all servers (aspnet/AspNetCore #7644).

AspNetCore. Kestrel 程序集Microsoft.AspNetCore.Server.Kestrel.Https assembly removed

在 ASP.NET Core 2.1 中,AspNetCore 的内容已移至 AspNetCore。 Kestrel. Kestrel的内容已移至。In ASP.NET Core 2.1, the contents of Microsoft.AspNetCore.Server.Kestrel.Https.dll were moved to Microsoft.AspNetCore.Server.Kestrel.Core.dll. 这是一个使用 TypeForwardedTo 特性的非重大更新。This was a non-breaking update using TypeForwardedTo attributes. 对于3.0,已删除AspNetCore程序集和 NuGet 包的空 Kestrel 程序集。For 3.0, the empty Microsoft.AspNetCore.Server.Kestrel.Https.dll assembly and the NuGet package have been removed.

引用AspNetCore的库应将 ASP.NET Core 依赖项更新为2.1 或更高版本。Libraries referencing Microsoft.AspNetCore.Server.Kestrel.Https should update ASP.NET Core dependencies to 2.1 or later.

目标为 ASP.NET Core 2.1 或更高版本的应用程序和库应删除对Kestrel包的任何直接引用。Apps and libraries targeting ASP.NET Core 2.1 or later should remove any direct references to the Microsoft.AspNetCore.Server.Kestrel.Https package.

Json.NET 支持Json.NET support

作为改善 ASP.NET Core 共享框架的工作的一部分,已从 ASP.NET Core 共享框架中删除Json.NETAs part of the work to improve the ASP.NET Core shared framework, Json.NET has been removed from the ASP.NET Core shared framework.

ASP.NET Core 的默认值现在是 .NET Core 3.0 中的新系统。The default for ASP.NET Core is now System.Text.Json, which is new in .NET Core 3.0. 如果可能,请考虑使用 System.Text.JsonConsider using System.Text.Json when possible. 它是高性能的,不需要额外的库依赖项。It's high-performance and doesn't require an additional library dependency. 但是,因为 System.Text.Json 是新的,所以它当前可能缺少你的应用程序所需的功能。However, since System.Text.Json is new, it might currently be missing features that your app needs.

如果你的应用程序使用 Newtonsoft.Json 特定的功能(例如 JsonPatch 或转换器),或者如果它格式化Newtonsoft.Json 特定的类型,则你的应用程序可能需要 Newtonsoft.Json 集成。Your app may require Newtonsoft.Json integration if it uses Newtonsoft.Json-specific feature such as JsonPatch or converters or if it formats Newtonsoft.Json-specific types.

若要在 ASP.NET Core 3.0 SignalR 项目中使用 Json.NET,请参阅本文档中的切换到 newtonsoft.json。To use Json.NET in an ASP.NET Core 3.0 SignalR project, see Switch to Newtonsoft.Json in this document.

在 ASP.NET Core 3.0 项目中使用 Json.NET:To use Json.NET in an ASP.NET Core 3.0 project:

  • 将包引用添加到 Microsoft.AspNetCore.Mvc.NewtonsoftJsonAdd a package reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson.

  • 更新 Startup.ConfigureServices 以调用 AddNewtonsoftJsonUpdate Startup.ConfigureServices to call AddNewtonsoftJson.

    services.AddMvc()
        .AddNewtonsoftJson();
    

    AddNewtonsoftJson 与新 MVC 服务注册方法兼容:AddNewtonsoftJson is compatible with the new MVC service registration methods:

    • AddRazorPages
    • AddControllersWithViews
    • AddControllers
    services.AddControllers()
        .AddNewtonsoftJson();
    

    可以在 AddNewtonsoftJson 调用中设置 Json.NET 设置:Json.NET settings can be set in the call to AddNewtonsoftJson:

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

MVC 服务注册MVC service registration

ASP.NET Core 3.0 添加了用于在 Startup.ConfigureServices 中注册 MVC 方案的新选项。ASP.NET Core 3.0 adds new options for registering MVC scenarios inside Startup.ConfigureServices.

IServiceCollection 上的 MVC 方案相关的三个新的顶级扩展方法可用。Three new top-level extension methods related to MVC scenarios on IServiceCollection are available. 模板使用这些新方法,而不是 AddMvcTemplates use these new methods instead of AddMvc. AddMvc 会继续按照以前版本中的方式进行。However, AddMvc continues to behave as it has in previous releases.

下面的示例添加了对控制器和 API 相关功能的支持,但不支持视图或页面。The following example adds support for controllers and API-related features, but not views or pages. API 模板使用以下代码:The API template uses this code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

下面的示例添加了对控制器、API 相关功能和视图(而不是页)的支持。The following example adds support for controllers, API-related features, and views, but not pages. Web 应用程序(MVC)模板使用以下代码:The Web Application (MVC) template uses this code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
}

以下示例添加了对 Razor Pages 和最小控制器支持的支持。The following example adds support for Razor Pages and minimal controller support. Web 应用程序模板使用以下代码:The Web Application template uses this code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
}

新方法也可以组合在一起。The new methods can also be combined. 下面的示例等效于在 ASP.NET Core 2.2 中调用 AddMvcThe following example is equivalent to calling AddMvc in ASP.NET Core 2.2:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
}

路由启动代码Routing startup code

如果应用调用 UseMvcUseSignalR,则将应用迁移到终结点路由(如果可能)。If an app calls UseMvc or UseSignalR, migrate the app to Endpoint Routing if possible. 若要改善与以前版本的 MVC 的终结点路由兼容性,我们已还原 ASP.NET Core 2.2 中引入的 URL 生成的某些更改。To improve Endpoint Routing compatibility with previous versions of MVC, we've reverted some of the changes in URL generation introduced in ASP.NET Core 2.2. 如果在2.2 中使用终结点路由时遇到问题,则需要 ASP.NET Core 3.0 中的改进,但有以下例外:If you experienced problems using Endpoint Routing in 2.2, expect improvements in ASP.NET Core 3.0 with the following exceptions:

  • 如果应用实现 IRouter 或继承自 Route,请使用DynamicRouteValuesTransformer作为替换项。If the app implements IRouter or inherits from Route, use DynamicRouteValuesTransformer as the replacement.

  • 如果应用直接访问 MVC 内的 RouteData.Routers 来分析 Url,则可以将其替换为 LinkParser.ParsePathByEndpointName 的使用。If the app directly accesses RouteData.Routers inside MVC to parse URLs, you can replace this with use of LinkParser.ParsePathByEndpointName.

  • 使用路由名称定义路由。Define the route with a route name.

  • 使用 LinkParser.ParsePathByEndpointName 并传入所需的路由名称。Use LinkParser.ParsePathByEndpointName and pass in the desired route name.

终结点路由支持与 IRouter 相同的路由模式语法和路由模式创作功能。Endpoint Routing supports the same route pattern syntax and route pattern authoring features as IRouter. 终结点路由支持 IRouteConstraintEndpoint Routing supports IRouteConstraint. 终结点路由支持 [Route][HttpGet] 和其他 MVC 路由属性。Endpoint routing supports [Route], [HttpGet], and the other MVC routing attributes.

对于大多数应用程序,只 Startup 需要更改。For most applications, only Startup requires changes.

迁移启动。配置Migrate Startup.Configure

一般建议:General advice:

  • 添加 UseRoutingAdd UseRouting.

  • 如果应用调用 UseStaticFiles,请将 UseStaticFiles 置于 UseRouting之前If the app calls UseStaticFiles, place UseStaticFiles before UseRouting.

  • 如果应用使用身份验证/授权功能(如 AuthorizePage[Authorize]),请将对 UseAuthenticationUseAuthorization 的调用放在之后UseRoutingUseCors,但在 UseEndpoints 之前:If the app uses authentication/authorization features such as AuthorizePage or [Authorize], place the call to UseAuthentication and UseAuthorization: after, UseRouting and UseCors, but before UseEndpoints:

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • UseEndpoints 替换 UseMvcUseSignalRReplace UseMvc or UseSignalR with UseEndpoints.

  • 如果应用使用cors方案(如 [EnableCors]),请将对 UseCors 的调用放置在使用 cors 的任何其他中间件之前(例如,将 UseCors 置于 UseAuthenticationUseAuthorizationUseEndpoints 之前)。If the app uses CORS scenarios, such as [EnableCors], place the call to UseCors before any other middleware that use CORS (for example, place UseCors before UseAuthentication, UseAuthorization, and UseEndpoints).

  • IHostingEnvironment 替换为 IWebHostEnvironment,并为 Microsoft.Extensions.Hosting 命名空间添加 using 语句。Replace IHostingEnvironment with IWebHostEnvironment and add a using statement for the Microsoft.Extensions.Hosting namespace.

  • IApplicationLifetime 替换为 IHostApplicationLifetimeMicrosoft.Extensions.Hosting 命名空间)。Replace IApplicationLifetime with IHostApplicationLifetime (Microsoft.Extensions.Hosting namespace).

  • EnvironmentName 替换为 EnvironmentsMicrosoft.Extensions.Hosting 命名空间)。Replace EnvironmentName with Environments (Microsoft.Extensions.Hosting namespace).

以下代码是典型的 ASP.NET Core 2.2 应用中 Startup.Configure 的示例:The following code is an example of Startup.Configure in a typical ASP.NET Core 2.2 app:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseSignalR(hubs =>
    {
        hubs.MapHub<ChatHub>("/chat");
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

更新上一个 Startup.Configure 代码后:After updating the previous Startup.Configure code:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chat");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

警告

对于大多数应用,对 UseAuthenticationUseAuthorizationUseCors 的调用必须出现在对 UseRouting 的调用之间,然后 UseEndpoints 才有效。For most apps, calls to UseAuthentication, UseAuthorization, and UseCors must appear between the calls to UseRouting and UseEndpoints to be effective.

运行状况检查Health Checks

运行状况检查将终结点路由与泛型主机一起使用。Health Checks use endpoint routing with the Generic Host. Startup.Configure 内,使用终结点 URL 或相对路径在终结点生成器上调用 MapHealthChecksIn Startup.Configure, call MapHealthChecks on the endpoint builder with the endpoint URL or relative path:

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

运行状况检查终结点可以:Health Checks endpoints can:

  • 指定一个或多个允许的主机/端口。Specify one or more permitted hosts/ports.
  • 需要授权。Require authorization.
  • 需要 CORS。Require CORS.

有关更多信息,请参见ASP.NET Core 中的运行状况检查For more information, see ASP.NET Core 中的运行状况检查.

安全中间件指南Security middleware guidance

对授权和 CORS 的支持是围绕中间件方法统一的。Support for authorization and CORS is unified around the middleware approach. 这允许在这些情况下使用相同的中间件和功能。This allows use of the same middleware and functionality across these scenarios. 此版本提供了更新的授权中间件,并增强了 CORS 中间件,使其能够理解 MVC 控制器使用的属性。An updated authorization middleware is provided in this release, and CORS Middleware is enhanced so that it can understand the attributes used by MVC controllers.

CORSCORS

以前,CORS 可能比较困难。Previously, CORS could be difficult to configure. 在某些用例中提供了中间件,但在其他用例中使用中间件即可使用 MVC 筛选器。Middleware was provided for use in some use cases, but MVC filters were intended to be used without the middleware in other use cases. 使用 ASP.NET Core 3.0,建议所有需要 CORS 的应用都将 CORS 中间件与端点路由一起使用。With ASP.NET Core 3.0, we recommend that all apps that require CORS use the CORS Middleware in tandem with Endpoint Routing. UseCors 可以与默认策略一起提供,并且可以使用 [EnableCors][DisableCors] 特性来重写所需的默认策略。UseCors can be provided with a default policy, and [EnableCors] and [DisableCors] attributes can be used to override the default policy where required.

如下示例中:In the following example:

  • 已为所有终结点(名为 default 的策略)启用 CORS。CORS is enabled for all endpoints with the default named policy.
  • @No__t_0 类将通过 [DisableCors] 特性来禁用 CORS。The MyController class disables CORS with the [DisableCors] attribute.
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseCors("default");

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[DisableCors]
public class MyController : ControllerBase
{
    ...
}

授权Authorization

在早期版本的 ASP.NET Core 中,通过 [Authorize] 属性提供授权支持。In earlier versions of ASP.NET Core, authorization support was provided via the [Authorize] attribute. 授权中间件不可用。Authorization middleware wasn't available. 在 ASP.NET Core 3.0 中,授权中间件是必需的。In ASP.NET Core 3.0, authorization middleware is required. 建议在 UseAuthentication 之后立即放置 ASP.NET Core 授权中间件(UseAuthorization)。We recommend placing the ASP.NET Core Authorization Middleware (UseAuthorization) immediately after UseAuthentication. 授权中间件还可以使用默认策略进行配置,该策略可以重写。The Authorization Middleware can also be configured with a default policy, which can be overridden.

在 ASP.NET Core 3.0 或更高版本中,UseAuthorizationStartup.Configure 中调用,以下 HomeController 需要已登录的用户:In ASP.NET Core 3.0 or later, UseAuthorization is called in Startup.Configure, and the following HomeController requires a signed in user:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

public class HomeController : ControllerBase
{
    [Authorize]
    public IActionResult BuyWidgets()
    {
        ...
    }
}

如果应用将 AuthorizeFilter 用作 MVC 中的全局筛选器,我们建议重构代码,以便在对 AddAuthorization 的调用中提供策略。If the app uses an AuthorizeFilter as a global filter in MVC, we recommend refactoring the code to provide a policy in the call to AddAuthorization.

@No__t_0 最初配置为要求身份验证,因此无需进行其他配置。The DefaultPolicy is initially configured to require authentication, so no additional configuration is required. 在下面的示例中,MVC 端点标记为 RequireAuthorization 以便所有请求都必须基于 DefaultPolicy 进行授权。In the following example, MVC endpoints are marked as RequireAuthorization so that all requests must be authorized based on the DefaultPolicy. 但是,HomeController 允许在用户登录到应用时不登录,因为 [AllowAnonymous]However, the HomeController allows access without the user signing into the app due to [AllowAnonymous]:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : ControllerBase
{
    ...
}

还可以自定义策略。Policies can also be customized. 基于前面的示例,将 DefaultPolicy 配置为要求身份验证和特定作用域:Building upon the previous example, the DefaultPolicy is configured to require authentication and a specific scope:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : ControllerBase
{
    ...
}

或者,通过配置 FallbackPolicy,可以将所有终结点配置为要求无 [Authorize]RequireAuthorization 的授权。Alternatively, all endpoints can be configured to require authorization without [Authorize] or RequireAuthorization by configuring a FallbackPolicy. @No__t_0 与 DefaultPolicy 不同。The FallbackPolicy is different from the DefaultPolicy. @No__t_0 由 [Authorize]RequireAuthorization 触发,而当未设置其他策略时,将触发 FallbackPolicyThe DefaultPolicy is triggered by [Authorize] or RequireAuthorization, while the FallbackPolicy is triggered when no other policy is set. FallbackPolicy 最初配置为允许未经授权的请求。FallbackPolicy is initially configured to allow requests without authorization.

下面的示例与前面 DefaultPolicy 示例相同,但使用 FallbackPolicy 总是要求对所有终结点进行身份验证,但指定 [AllowAnonymous] 时除外:The following example is the same as the preceding DefaultPolicy example but uses the FallbackPolicy to always require authentication on all endpoints except when [AllowAnonymous] is specified:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[AllowAnonymous]
public class HomeController : ControllerBase
{
    ...
}

中间件的授权工作正常,无需使用任何特定的授权知识。Authorization by middleware works without the framework having any specific knowledge of authorization. 例如,运行状况检查没有特定的授权知识,但运行状况检查可以具有由中间件应用的可配置授权策略。For instance, health checks has no specific knowledge of authorization, but health checks can have a configurable authorization policy applied by the middleware.

此外,每个终结点都可以自定义其授权要求。Additionally, each endpoint can customize its authorization requirements. 在下面的示例中,UseAuthorization 处理 DefaultPolicy 的授权,但是 /healthz 运行状况检查终结点需要 admin 用户:In the following example, UseAuthorization processes authorization with the DefaultPolicy, but the /healthz health check endpoint requires an admin user:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapHealthChecks("/healthz")
            .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
    });
}

在某些情况下,实现保护。Protection is implemented for some scenarios. 如果由于缺少中间件而跳过授权或 CORS 策略,则终结点中间件会引发异常。Endpoints Middleware throws an exception if an authorization or CORS policy is skipped due to missing middleware. 提供有关配置错误的其他反馈的分析器支持。Analyzer support to provide additional feedback about misconfiguration is in progress.

SignalRSignalR

SignalR 集线器的映射现在发生在 UseEndpointsMapping of SignalR hubs now takes place inside UseEndpoints.

将每个集线器映射 MapHubMap each hub with MapHub. 与早期版本一样,每个中心都显式列出。As in previous versions, each hub is explicitly listed.

在以下示例中,添加了对 ChatHub SignalR 中心的支持:In the following example, support for the ChatHub SignalR hub is added:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>();
    });
}

有一个新的选项可用于控制来自客户端的消息大小限制。There is a new option for controlling message size limits from clients. 例如,在 Startup.ConfigureServicesFor example, in Startup.ConfigureServices:

services.AddSignalR(hubOptions =>
{
    hubOptions.MaximumReceiveMessageSize = 32768;
});

在 ASP.NET Core 2.2 中,可以设置 TransportMaxBufferSize 并有效控制最大消息大小。In ASP.NET Core 2.2, you could set the TransportMaxBufferSize and that would effectively control the maximum message size. 在 ASP.NET Core 3.0 中,该选项现在仅控制观察反压之前的最大大小。In ASP.NET Core 3.0, that option now only controls the maximum size before backpressure is observed.

MVC 控制器MVC controllers

控制器的映射现在发生在 UseEndpointsMapping of controllers now takes place inside UseEndpoints.

如果应用使用属性路由,则添加 MapControllersAdd MapControllers if the app uses attribute routing. 由于路由包括对 ASP.NET Core 3.0 或更高版本中的多个框架的支持,因此添加属性路由控制器是可选的。Since routing includes support for many frameworks in ASP.NET Core 3.0 or later, adding attribute-routed controllers is opt-in.

替换以下内容:Replace the following:

  • MapRouteMapControllerRouteMapRoute with MapControllerRoute
  • MapAreaRouteMapAreaControllerRouteMapAreaRoute with MapAreaControllerRoute

由于路由现在不仅包括对 MVC 的支持,术语已更改,使这些方法清楚地说明它们的作用。Since routing now includes support for more than just MVC, the terminology has changed to make these methods clearly state what they do. 传统路由(例如 MapControllerRoute / MapAreaControllerRoute / MapDefaultControllerRoute 将按照它们的添加顺序进行应用。Conventional routes such as MapControllerRoute/MapAreaControllerRoute/MapDefaultControllerRoute are applied in the order that they're added. 首先放置更具体的路由(如区域的路由)。Place more specific routes (such as routes for an area) first.

如下示例中:In the following example:

  • MapControllers 增加了对属性路由控制器的支持。MapControllers adds support for attribute-routed controllers.
  • MapAreaControllerRoute 为某个区域中的控制器添加传统路由。MapAreaControllerRoute adds a conventional route for controllers in an area.
  • MapControllerRoute 为控制器添加传统路由。MapControllerRoute adds a conventional route for controllers.
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapAreaControllerRoute(
            "admin",
            "admin",
            "Admin/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllerRoute(
            "default", "{controller=Home}/{action=Index}/{id?}");
    });
}

从控制器操作名称中删除 Async 后缀Async suffix removal from controller action names

在 ASP.NET Core 3.0 中,ASP.NET Core MVC 从控制器操作名称中删除 Async 后缀。In ASP.NET Core 3.0, ASP.NET Core MVC removes the Async suffix from controller action names. 此新默认设置会影响路由和链接的生成。Both routing and link generation are impacted by this new default. 例如:For example:

public class ProductsController : Controller
{
    public async Task<IActionResult> ListAsync()
    {
        var model = await _dbContext.Products.ToListAsync();
        return View(model);
    }
}

在 ASP.NET Core 3.0 之前:Prior to ASP.NET Core 3.0:

  • 可以在Products/batchmanagementclient.account.listasync路由中访问上述操作。The preceding action could be accessed at the Products/ListAsync route.

  • 需要指定 Async 后缀的链接生成。Link generation required specifying the Async suffix. 例如:For example:

    <a asp-controller="Products" asp-action="ListAsync">List</a>
    

在 ASP.NET Core 3.0:In ASP.NET Core 3.0:

  • 可以在产品/列表路由上访问上述操作。The preceding action can be accessed at the Products/List route.

  • 链接生成不需要指定 Async 后缀。Link generation doesn't require specifying the Async suffix. 例如:For example:

    <a asp-controller="Products" asp-action="List">List</a>
    

此更改不会影响使用[ActionName]属性指定的名称。This change doesn't affect names specified using the [ActionName] attribute. 可以通过 Startup.ConfigureServices 中的以下代码禁用默认行为:The default behavior can be disabled with the following code in Startup.ConfigureServices:

services.AddMvc(options =>
    options.SuppressAsyncSuffixInActionNames = false);

Razor 页面Razor Pages

映射 Razor Pages 现在发生在 UseEndpoints 内。Mapping Razor Pages now takes place inside UseEndpoints.

如果应用使用 Razor Pages,则添加 MapRazorPagesAdd MapRazorPages if the app uses Razor Pages. 由于终结点路由包含对多个框架的支持,因此添加 Razor Pages 现在将选择加入。Since Endpoint Routing includes support for many frameworks, adding Razor Pages is now opt-in.

在下面 Startup.Configure 方法中,MapRazorPages 增加了对 Razor Pages 的支持:In the following Startup.Configure method, MapRazorPages adds support for Razor Pages:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

使用不带终结点路由的 MVCUse MVC without Endpoint Routing

若要在 ASP.NET Core 3.0 中通过 UseMvcUseMvcWithDefaultRoute 使用 MVC,需要在 Startup.ConfigureServices 内显式选择加入。Using MVC via UseMvc or UseMvcWithDefaultRoute in ASP.NET Core 3.0 requires an explicit opt-in inside Startup.ConfigureServices. 这是必需的,因为 MVC 必须知道它是否可以在初始化期间依赖于授权和 CORS 中间件。This is required because MVC must know whether it can rely on the authorization and CORS Middleware during initialization. 如果应用程序尝试使用不受支持的配置,则会发出警告。An analyzer is provided that warns if the app attempts to use an unsupported configuration.

如果应用需要旧的 IRouter 支持,请使用 Startup.ConfigureServices 中的以下任意方法禁用 EnableEndpointRoutingIf the app requires legacy IRouter support, disable EnableEndpointRouting using any of the following approaches in Startup.ConfigureServices:

services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);

运行状况检查Health checks

运行状况检查可用作使用终结点路由的路由器软件。Health checks can be used as a router-ware with Endpoint Routing.

添加 MapHealthChecks 以将运行状况检查与终结点路由一起使用。Add MapHealthChecks to use health checks with Endpoint Routing. @No__t_0 方法接受类似于 UseHealthChecks 的参数。The MapHealthChecks method accepts arguments similar to UseHealthChecks. 使用 MapHealthChecks 超出 UseHealthChecks 的优点是能够应用授权,并对匹配策略进行更精细的控制。The advantage of using MapHealthChecks over UseHealthChecks is the ability to apply authorization and to have greater fine-grained control over the matching policy.

在下面的示例中,为 /healthz 上的运行状况检查终结点调用 MapHealthChecksIn the following example, MapHealthChecks is called for a health check endpoint at /healthz:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
    });
}

HostBuilder 替换 WebHostBuilderHostBuilder replaces WebHostBuilder

ASP.NET Core 3.0 模板使用泛型主机The ASP.NET Core 3.0 templates use Generic Host. 以前的版本使用Web 主机Previous versions used Web Host. 下面的代码显示 Program 类生成的 ASP.NET Core 3.0 模板:The following code shows the ASP.NET Core 3.0 template generated Program class:

// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;

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

下面的代码演示 ASP.NET Core 2.2 模板生成的 Program 类:The following code shows the ASP.NET Core 2.2 template-generated Program class:

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

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

IWebHostBuilder 保留在3.0,并且是前面的代码示例中所见 webBuilder 的类型。IWebHostBuilder remains in 3.0 and is the type of the webBuilder seen in the preceding code sample. 在未来版本中将弃用 WebHostBuilder,并将其替换为 HostBuilderWebHostBuilder will be deprecated in a future release and replaced by HostBuilder.

WebHostBuilderHostBuilder 的最重大更改是在依赖关系注入(DI)中进行的。The most significant change from WebHostBuilder to HostBuilder is in dependency injection (DI). 使用 HostBuilder 时,只能将 IConfigurationIHostingEnvironment 插入 Startup 的构造函数中。When using HostBuilder, you can only inject IConfiguration and IHostingEnvironment into Startup's constructor. @No__t_0 DI 约束:The HostBuilder DI constraints:

  • 启用仅生成一次 DI 容器。Enable the DI container to be built only one time.
  • 避免产生的对象生存期问题,如解析多个单一实例实例。Avoids the resulting object lifetime issues like resolving multiple instances of singletons.

AddAuthorization 已移动到不同的程序集AddAuthorization moved to a different assembly

AspNetCore中的 ASP.NET Core 2.2 和更低 AddAuthorization 方法:The ASP.NET Core 2.2 and lower AddAuthorization methods in Microsoft.AspNetCore.Authorization.dll:

  • 已重命名 AddAuthorizationCoreHave been renamed AddAuthorizationCore.
  • 已被移动到AspNetCore中。Have been moved to Microsoft.AspNetCore.Authorization.Policy.dll.

同时使用AspNetCoreAspNetCore的应用都不会受到任何影响。)。Apps that are using both Microsoft.AspNetCore.Authorization.dll and Microsoft.AspNetCore.Authorization.Policy.dll aren't impacted.

不是使用AspNetCore的应用程序应执行以下操作之一:Apps that are not using Microsoft.AspNetCore.Authorization.Policy.dll should do one of the following:

  • 切换到使用 AddAuthorizationCoreSwitch to using AddAuthorizationCore
  • 将引用添加到AspNetCore中。Add a reference to Microsoft.AspNetCore.Authorization.Policy.dll.

有关详细信息,请参阅AddAuthorization(o => 中的重大更改 #386 中存在不同的程序集For more information, see Breaking change in AddAuthorization(o =>) overload lives in a different assembly #386.

SignalRSignalR

SignalR JavaScript 客户端已从 @aspnet/signalr 更改为 @microsoft/signalrThe SignalR JavaScript client has changed from @aspnet/signalr to @microsoft/signalr. 若要对此更改做出反应,请更改package文件、require 语句和 ECMAScript import 语句中的引用。To react to this change, change the references in package.json files, require statements, and ECMAScript import statements.

System.web 是默认协议System.Text.Json is the default protocol

System.Text.Json 现在是客户端和服务器使用的默认集线器协议。System.Text.Json is now the default Hub protocol used by both the client and server.

Startup.ConfigureServices 中,调用 AddJsonProtocol 设置序列化程序选项。In Startup.ConfigureServices, call AddJsonProtocol to set serializer options.

服务Server:

services.AddSignalR(...)
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        })

客户端:Client:

new HubConnectionBuilder()
    .WithUrl("/chatHub")
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.WriteIndented = false;
    })
    .Build();

切换到 Newtonsoft.jsonSwitch to Newtonsoft.Json

如果正在使用 System.Text.Json 不支持的 Newtonsoft.Json 功能,可以切换回 Newtonsoft.JsonIf you're using features of Newtonsoft.Json that aren't supported in System.Text.Json, you can switch back to Newtonsoft.Json:

  1. 安装AspNetCore SignalR NewtonsoftJson NuGet 包。Install the Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson NuGet package.

  2. 在客户端上,将 AddNewtonsoftJsonProtocol 方法调用链接到 HubConnectionBuilder 实例:On the client, chain an AddNewtonsoftJsonProtocol method call to the HubConnectionBuilder instance:

    new HubConnectionBuilder()
        .WithUrl("/chatHub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  3. 在服务器上,将 AddNewtonsoftJsonProtocol 方法调用链接到 Startup.ConfigureServices 中的 AddSignalR 方法调用:On the server, chain an AddNewtonsoftJsonProtocol method call to the AddSignalR method call in Startup.ConfigureServices:

    services.AddSignalR()
        .AddNewtonsoftJsonProtocol(...);
    

选择启用运行时编译Opt in to runtime compilation

在 ASP.NET Core 3.0 之前,视图的运行时编译是框架的隐式功能。Prior to ASP.NET Core 3.0, runtime compilation of views was an implicit feature of the framework. 运行时编译对视图的生成时编译进行了补充。Runtime compilation supplements build-time compilation of views. 它允许框架在修改文件时编译 Razor 视图和页面(cshtml文件),而无需重新生成整个应用。It allows the framework to compile Razor views and pages (.cshtml files) when the files are modified, without having to rebuild the entire app. 此功能支持在 IDE 中进行快速编辑并刷新浏览器以查看更改的方案。This feature supports the scenario of making a quick edit in the IDE and refreshing the browser to view the changes.

在 ASP.NET Core 3.0 中,运行时编译是一个可选方案。In ASP.NET Core 3.0, runtime compilation is an opt-in scenario. 生成时编译是默认情况下启用的视图编译机制。Build-time compilation is the only mechanism for view compilation that's enabled by default. 当检测到dotnet文件的更改时,运行时依赖于 Visual Studio 或 Visual Studio Code 以重新生成项目。The runtime relies on Visual Studio or dotnet-watch in Visual Studio Code to rebuild the project when it detects changes to .cshtml files. 在 Visual Studio 中,将运行的项目(Ctrl + F5)更改为 .cs、.csrazor 文件,但不进行调试(F5),这会触发项目的重新编译。In Visual Studio, changes to .cs, .cshtml, or .razor files in the project being run (Ctrl+F5), but not debugged (F5), trigger recompilation of the project.

在 ASP.NET Core 3.0 项目中启用运行时编译:To enable runtime compilation in your ASP.NET Core 3.0 project:

  1. 安装 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet 包。Install the Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet package.

  2. 更新 Startup.ConfigureServices 以调用 AddRazorRuntimeCompilationUpdate Startup.ConfigureServices to call AddRazorRuntimeCompilation:

    对于 ASP.NET Core MVC,请使用以下代码:For ASP.NET Core MVC, use the following code:

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    对于 ASP.NET Core Razor Pages,请使用以下代码:For ASP.NET Core Razor Pages, use the following code:

    services.AddRazorPages()
        .AddRazorRuntimeCompilation(...);
    

@No__t_0 的示例演示了在开发环境中有条件地启用运行时编译的示例。The sample at https://github.com/aspnet/samples/tree/master/samples/aspnetcore/mvc/runtimecompilation shows an example of enabling runtime compilation conditionally in Development environments.

有关 Razor 文件编译的详细信息,请参阅 ASP.NET Core 中的 Razor 文件编译For more information on Razor file compilation, see ASP.NET Core 中的 Razor 文件编译.

通过多目标迁移库Migrate libraries via multi-targeting

库通常需要支持 ASP.NET Core 的多个版本。Libraries often need to support multiple versions of ASP.NET Core. 针对以前版本的 ASP.NET Core 编译的大多数库应继续正常运行。Most libraries that were compiled against previous versions of ASP.NET Core should continue working without issues. 以下条件要求对应用进行交叉编译:The following conditions require the app to be cross-compiled:

  • 库依赖于具有二进制重大更改的功能。The library relies on a feature that has a binary breaking change.
  • 库需要利用 ASP.NET Core 3.0 中的新增功能。The library wants to take advantage of new features in ASP.NET Core 3.0.

例如:For example:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
  </ItemGroup>
</Project>

使用 #ifdefs 可启用 ASP.NET Core 3.0 特定的 Api:Use #ifdefs to enable ASP.NET Core 3.0-specific APIs:

var webRootFileProvider =
#if NETCOREAPP3_0
    GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
    GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif

发布Publish

删除项目目录中的binobj文件夹。Delete the bin and obj folders in the project directory.

TestServerTestServer

对于直接使用TestServer 的应用,请在ConfigureWebHost 中的 IWebHostBuilder 上创建 TestServerFor apps that use TestServer directly with the Generic Host, create the TestServer on an IWebHostBuilder in ConfigureWebHost:

[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .Configure(app => { });
        })
    .StartAsync();

    var response = await host.GetTestServer().CreateClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

中断 API 更改Breaking API changes

查看重大更改:Review breaking changes:

Azure App Service 上的 .NET Core 3。0.NET Core 3.0 on Azure App Service

有关将 .NET Core 部署到 Azure App Service 的进度,请参阅应用服务网站上的官方 .Net coreFor progress on the rollout of .NET Core to Azure App Service, see the official .NET Core on App Service website. 在 Azure App Service 中提供 .NET Core 3.0 之前,请按照将ASP.NET Core 预览版部署到 Azure App Service中的说明进行操作。Until .NET Core 3.0 is available on Azure App Service, follow the instructions at Deploy ASP.NET Core preview release to Azure App Service.