从 ASP.NET Core 3.1 迁移到 5.0

本文介绍如何将现有 ASP.NET Core 3.1 项目更新为 ASP.NET Core 5.0。 有关如何从 ASP.NET Core 3.1 迁移到 ASP.NET Core 6.0 的说明,请参阅从 ASP.NET Core 3.1 迁移到 6.0

先决条件

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

如果依靠 global.json 文件来定向于特定 .NET Core SDK 版本,请将 version 属性更新为已安装的 .NET 5.0 SDK 版本。 例如:

{
  "sdk": {
-    "version": "3.1.200"
+    "version": "5.0.100"
  }
}

更新目标框架

如果更新 Blazor WebAssembly 项目,请跳到更新 Blazor WebAssembly 项目部分。 对于任何其他 ASP.NET Core 项目类型,请将项目文件的目标框架名字对象 (TFM) 更新为 net5.0

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

  <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

</Project>

删除 binobj 文件夹

可能需要删除 binobj 文件夹。 运行 dotnet nuget locals --clear all 以清除 NuGet 包缓存。

5.0.1 和更高的 5.x(最高可达 6.0)版本中对 Blazor 应用路由逻辑的更改

在 ASP.NET Core 5.0.1 补丁版本中,路由优先级的计算发生了变化。 如果定义了“全部捕获”路由或带可选参数的路由,这可能会造成影响。

旧行为

在 ASP.NET Core 5.0.0 或更早版本中,先前的行为是优先级较低的路由(例如 {*slug})在优先级较高的路由(例如 /customer/{id})之前进行匹配。

新行为

在 ASP.NET Core 5.0.1 或更高版本中,新行为更接近于 ASP.NET Core 应用中定义的路由行为,其中,框架将首先计算并建立每个段的路由优先级,并且只使用中断绑定的路由长度作为次要条件。

更改原因

原始行为被视为实现中的 bug,因为我们的目标是使 Blazor 路由系统的行为与 ASP.NET Core 路由系统中 Blazor 路由支持的功能子集的行为相同。

PreferExactMatches 属性添加到 App.razor 文件中的 Router 组件,以选择正确的行为:

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">

如果将 PreferExactMatches 设置为 @true,则路由匹配将优先选取精确匹配而非通配符匹配。

重要

所有应用都应显式将 PreferExactMatches 设置为 @true

提供将 PreferExactMatches 设置为 @false 或将其保留为未设置的功能仅用于实现后向兼容性。

.NET 6 发布后,路由器将始终首选完全匹配项,PreferExactMatches 选项将不可用。

更新 Blazor WebAssembly 和 Blazor Server 项目

本部分中的指南适用于两种 Blazor 托管模型。 本部分后面的章节提供特定于托管模型和应用类型的其他指南。 将所有相关部分的指南应用于你的应用。

  1. 在 Blazor WebAssembly 应用的 wwwroot/index.html 中,或 Blazor Server 应用的 Pages/_Host.cshtml 中,将 <link> 元素添加到 <head> 元素以实现不同的样式。 在下面的 <link> 元素 href 属性值中,占位符 {ASSEMBLY NAME} 是应用的程序集名称。

    +<link href="{ASSEMBLY NAME}.styles.css" rel="stylesheet" />
    

    独立 Blazor WebAssembly 或 Blazor Server 示例:

    +<link href="BlazorSample.styles.css" rel="stylesheet" />
    

    托管的 Blazor WebAssembly 解决方案的 Client 项目示例:

    +<link href="BlazorSample.Client.styles.css" rel="stylesheet" />
    
  2. 在应用的 _Imports.razor 文件中包括新的命名空间,以实现组件虚拟化Microsoft.AspNetCore.Components.Web.Virtualization。 下面的 _Imports.razor 文件显示了从 Blazor 项目模板生成的应用中的默认命名空间。 占位符 {ASSEMBLY NAME} 是应用的程序集名称。

    Blazor WebAssembly (_Imports.razor):

    @using System.Net.Http
    @using System.Net.Http.Json
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.AspNetCore.Components.Web.Virtualization
    @using Microsoft.AspNetCore.Components.WebAssembly.Http
    @using Microsoft.JSInterop
    @using {ASSEMBLY NAME}
    @using {ASSEMBLY NAME}.Shared
    

    Blazor Server (_Imports.razor):

    @using System.Net.Http
    @using Microsoft.AspNetCore.Authorization
    @using Microsoft.AspNetCore.Components.Authorization
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.AspNetCore.Components.Web.Virtualization
    @using Microsoft.JSInterop
    @using {ASSEMBLY NAME}
    @using {ASSEMBLY NAME}.Shared
    
  3. MainLayout 组件 (Shared/MainLayout.razor) 中,将组件的 HTML 标记括在 class 属性设置为 page<div> 元素中:

    <div class="page">
    
        ...
    
    </div>
    
  4. 将以下文件添加到 Shared 文件夹:

    MainLayout.razor.css:

    .page {
        position: relative;
        display: flex;
        flex-direction: column;
    }
    
    .main {
        flex: 1;
    }
    
    .sidebar {
        background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
    }
    
    .top-row {
        background-color: #f7f7f7;
        border-bottom: 1px solid #d6d5d5;
        justify-content: flex-end;
        height: 3.5rem;
        display: flex;
        align-items: center;
    }
    
        .top-row ::deep a, .top-row .btn-link {
            white-space: nowrap;
            margin-left: 1.5rem;
        }
    
        .top-row a:first-child {
            overflow: hidden;
            text-overflow: ellipsis;
        }
    
    @media (max-width: 767.98px) {
        .top-row:not(.auth) {
            display: none;
        }
    
        .top-row.auth {
            justify-content: space-between;
        }
    
        .top-row a, .top-row .btn-link {
            margin-left: 0;
        }
    }
    
    @media (min-width: 768px) {
        .page {
            flex-direction: row;
        }
    
        .sidebar {
            width: 250px;
            height: 100vh;
            position: sticky;
            top: 0;
        }
    
        .top-row {
            position: sticky;
            top: 0;
            z-index: 1;
        }
    
        .main > div {
            padding-left: 2rem !important;
            padding-right: 1.5rem !important;
        }
    }
    

    NavMenu.razor.css:

    .navbar-toggler {
        background-color: rgba(255, 255, 255, 0.1);
    }
    
    .top-row {
        height: 3.5rem;
        background-color: rgba(0,0,0,0.4);
    }
    
    .navbar-brand {
        font-size: 1.1rem;
    }
    
    .oi {
        width: 2rem;
        font-size: 1.1rem;
        vertical-align: text-top;
        top: -2px;
    }
    
    .nav-item {
        font-size: 0.9rem;
        padding-bottom: 0.5rem;
    }
    
        .nav-item:first-of-type {
            padding-top: 1rem;
        }
    
        .nav-item:last-of-type {
            padding-bottom: 1rem;
        }
    
        .nav-item ::deep a {
            color: #d7d7d7;
            border-radius: 4px;
            height: 3rem;
            display: flex;
            align-items: center;
            line-height: 3rem;
        }
    
    .nav-item ::deep a.active {
        background-color: rgba(255,255,255,0.25);
        color: white;
    }
    
    .nav-item ::deep a:hover {
        background-color: rgba(255,255,255,0.1);
        color: white;
    }
    
    @media (min-width: 768px) {
        .navbar-toggler {
            display: none;
        }
    
        .collapse {
            /* Never collapse the sidebar for wide screens */
            display: block;
        }
    }
    
  5. Blazor WebAssembly 应用的最新基础 wwwroot/css/app.css 文件或 Blazor Server 应用的 wwwroot/css/site.css 文件包括以下样式。 删除其他样式,使其保留以下样式和任何已添加到应用的样式。

    以下样式表仅包含基本样式,不包括开发人员添加的自定义样式:

    html, body {
        font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    }
    
    a, .btn-link {
        color: #0366d6;
    }
    
    .btn-primary {
        color: #fff;
        background-color: #1b6ec2;
        border-color: #1861ac;
    }
    
    .content {
        padding-top: 1.1rem;
    }
    
    .valid.modified:not([type=checkbox]) {
        outline: 1px solid #26b050;
    }
    
    .invalid {
        outline: 1px solid red;
    }
    
    .validation-message {
        color: red;
    }
    
    #blazor-error-ui {
        background: lightyellow;
        bottom: 0;
        box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
        display: none;
        left: 0;
        padding: 0.6rem 1.25rem 0.7rem 1.25rem;
        position: fixed;
        width: 100%;
        z-index: 1000;
    }
    
    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
    

    注意

    前面的示例未显示 Blazor 项目模板提供的 Open Iconic 图标 (open-iconic-bootstrap.css) 的 @import 指令。 Open Iconic 被其维护者放弃。

更新 Blazor WebAssembly 项目

请遵循前面更新 Blazor WebAssembly 和 Blazor Server 项目部分中的指导。

对于 Blazor WebAssembly 项目(包括托管的 Blazor 解决方案的 Client 项目),对项目文件应用以下更改:

  1. 将 SDK 从 Microsoft.NET.Sdk.Web 更新为 Microsoft.NET.Sdk.BlazorWebAssembly

    - <Project Sdk="Microsoft.NET.Sdk.Web">
    + <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    

    注意

    此更新仅适用于独立 Blazor WebAssembly 项目和托管的 Blazor 解决方案的 Client 项目。

  2. 更新以下属性:

    <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    
      <PropertyGroup>
    -     <TargetFramework>netstandard2.1</TargetFramework>
    -     <RazorLangVersion>3.0</RazorLangVersion>
    +     <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
    
  3. 删除对 Microsoft.AspNetCore.Components.WebAssembly.Build 的引用:

    <ItemGroup>
    -    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.1" PrivateAssets="all" />
    
  4. 将其他包更新到最新版本。 可在 NuGet.org 中找到最新版本。

  5. wwwroot/index.html 中,将加载 App 组件的元素更改为 id 设置为 app<div> 元素:

    -<app>Loading...</app>
    +<div id="app">Loading...</div>
    
  6. Program.Main (Program.cs) 中,通过向其添加哈希 #,将对 <app> 元素的引用更改为对 CSS 选择器的引用:

    -builder.RootComponents.Add<App>("app");
    +builder.RootComponents.Add<App>("#app");
    
  7. Program.Main (Program.cs) 中,将默认暂时性 HttpClient 注册更改为限定范围(如果存在):

    -builder.Services.AddTransient(sp => new HttpClient 
    -    { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    +builder.Services.AddScoped(sp => new HttpClient 
    +    { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    
  8. 在托管的 Blazor 解决方案的 Client 应用中的 Program.Main (Program.cs) 中:

    • 可以选择替换 builder.HostEnvironment.BaseAddress 以获取字符串客户端基址。
    • 将任何命名的临时客户端工厂注册更改为限定范围。
    -builder.Services.AddHttpClient("{APP NAMESPACE}.ServerAPI", 
    -    client => client.BaseAddress = new Uri("https://localhost:5001"))
    -    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    -builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>()
    -    .CreateClient("{APP NAMESPACE}.ServerAPI"));
    +builder.Services.AddHttpClient("{APP NAMESPACE}.ServerAPI", 
    +    client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    +    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
    +builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    +    .CreateClient("{APP NAMESPACE}.ServerAPI"));
    

    在上面的代码中,{APP NAMESPACE} 占位符是应用的命名空间。

使用 Microsoft 帐户的独立 Blazor WebAssembly 应用

请遵循前面更新 Blazor WebAssembly 和 Blazor Server 项目更新 Blazor WebAssembly 项目部分中的指导。

对于在 Azure 门户中注册的独立 Blazor WebAssembly 应用,若要使用适用于 Microsoft 帐户的 Microsoft Entra ID (ME-ID):

  • 应用需要 openidoffline_access 范围:

    options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
    
  • 在 Azure 门户应用注册“身份验证”边栏选项卡中:

    1. 删除 Web 平台配置。
    2. 使用应用的重定向 URI 添加单页应用程序平台配置。
    3. 禁用访问令牌和 ID 令牌的隐式授权。

有关详细信息,请参阅使用 Microsoft 帐户保护 ASP.NET Core Blazor WebAssembly 独立应用

使用 Microsoft Entra ID (ME-ID) 的独立 Blazor WebAssembly 应用

请遵循前面更新 Blazor WebAssembly 和 Blazor Server 项目更新 Blazor WebAssembly 项目部分中的指导。

对于在 Azure 门户中注册的独立 Blazor WebAssembly 应用,若要使用 Microsoft Entra ID (ME-ID):

  • 应用需要 https://graph.microsoft.com/User.Read 范围:

    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://graph.microsoft.com/User.Read");
    
  • 在 Azure 门户应用注册“身份验证”边栏选项卡中:

    1. 删除 Web 平台配置。
    2. 使用应用的重定向 URI 添加单页应用程序平台配置。
    3. 禁用访问令牌和 ID 令牌的隐式授权。

有关详细信息,请参阅使用 Microsoft Entra ID 保护 ASP.NET Core Blazor WebAssembly 独立应用

使用 Azure Active Directory (AAD) B2C 的独立 Blazor WebAssembly 应用

请遵循前面更新 Blazor WebAssembly 和 Blazor Server 项目更新 Blazor WebAssembly 项目部分中的指导。

对于在 Azure 门户中注册的独立 Blazor WebAssembly 应用,若要使用 Azure Active Directory (AAD) B2C:

  • 应用需要 openidoffline_access 范围:

    options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
    
  • 在 Azure 门户应用注册“身份验证”边栏选项卡中:

    1. 删除 Web 平台配置。
    2. 使用应用的重定向 URI 添加单页应用程序平台配置。
    3. 禁用访问令牌和 ID 令牌的隐式授权。

有关详细信息,请参阅使用 Azure Active Directory B2C 保护 ASP.NET Core Blazor WebAssembly 独立应用

使用 Microsoft Entra ID (ME-ID) 或 AAD B2C 的托管 Blazor WebAssembly 应用

请遵循前面更新 Blazor WebAssembly 和 Blazor Server 项目更新 Blazor WebAssembly 项目部分中的指导。

使用 AAD 或 AAD B2C 进行用户身份验证的托管 Blazor 解决方案的 Client 应用注册应使用单页应用程序 Azure 应用平台配置。

在 Azure 门户 Client 应用注册“身份验证”边栏选项卡中:

  1. 删除 Web 平台配置。
  2. 使用应用的重定向 URI 添加单页应用程序平台配置。
  3. 禁用访问令牌和 ID 令牌的隐式授权。

有关详细信息,请参阅:

更新托管 Blazor 解决方案的 Server 项目

按照前文部分中的指南操作:

按照本文中的一般指南更新托管 Blazor 解决方案的 Server 项目作为 ASP.NET Core 应用。

此外,使用 Microsoft Entra ID (ME-ID) 或 B2C 让用户向客户端 Blazor WebAssembly 应用进行身份验证的 Server 项目应采用新的 Microsoft Identity v2.0 包:

对于 AAD:

-<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="..." />
+<PackageReference Include="Microsoft.Identity.Web" Version="{VERSION}" />
+<PackageReference Include="Microsoft.Identity.Web.UI" Version="{VERSION}" />

对于 AAD B2C:

-<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" Version="..." />
+<PackageReference Include="Microsoft.Identity.Web" Version="{VERSION}" />
+<PackageReference Include="Microsoft.Identity.Web.UI" Version="{VERSION}" />

对于前面的包引用,请确定 NuGet.org 上 {VERSION} 占位符的包版本:

注意

托管 Blazor WebAssembly 解决方案中 Server 项目的 SDK 保留为 Microsoft.NET.Sdk.Web

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

有关详细信息,请参阅:

清理并重建解决方案

将应用或解决方案迁移到 .NET 5 后,请清理并重新生成应用或解决方案。 如果新的包引用和缓存的包之间存在包不兼容:

  1. 在命令 shell 中执行以下 dotnet nuget locals 命令来清除 NuGet 包缓存:

    dotnet nuget locals --clear all
    
  2. 清理并重新生成应用或解决方案。

疑难解答

按照 Blazor WebAssembly 安全主题末尾适用于应用的故障排除指导进行操作:

独立 Blazor WebAssembly 应用:

托管 Blazor WebAssembly 应用:

客户端无 Microsoft Entra ID (ME-ID) 授权

升级使用 AAD 进行身份验证的 Blazor WebAssembly 应用后,在用户使用 AAD 登录后,可能会收到有关对应用的登录回调的以下错误:

信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 授权失败。 不符合以下要求:DenyAnonymousAuthorizationRequirement:要求用户经过身份验证。

AAD 返回的登录回叫错误:

  • 错误:unauthorized_client
  • 说明:AADB2C90058: The provided application is not configured to allow public clients.

若要解决该错误:

  1. 在 Azure 门户中访问应用的清单
  2. allowPublicClient 属性设置为 nulltrue

更新 Blazor 渐进式 Web 应用程序 (PWA)

在 PWA 应用的项目文件中添加以下项:

<ItemGroup>
  <ServiceWorker Include="wwwroot\service-worker.js" 
    PublishedContent="wwwroot\service-worker.published.js" />
</ItemGroup>

如果项目的 wwwroot/index.html (Blazor WebAssembly) 或 Pages/_Host.cshtml (Blazor Server) 包含较早 5.0 预览版本中用于 scoped.styles.css 的样式表 <link> 元素,请删除 <link> 标记:

-<link href="_framework/scoped.styles.css/" rel="stylesheet" />

更新 Razor 类库 (RCL)

迁移 Razor 类库 (RCL),以利用 ASP.NET Core 5.0 中引入的新 API 或功能。

更新面向组件的 RCL:

  1. 更新项目文件中的以下属性:

    <Project Sdk="Microsoft.NET.Sdk.Razor">
    
      <PropertyGroup>
    -     <TargetFramework>netstandard2.0</TargetFramework>
    -     <RazorLangVersion>3.0</RazorLangVersion>
    +     <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
    
  2. 将其他包更新到最新版本。 可在 NuGet.org 中找到最新版本。

若要更新面向 MVC 的 RCL,请更新项目文件中的以下属性:

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

  <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

更新包引用

在项目文件中,将每个 Microsoft.AspNetCore.*Microsoft.EntityFrameworkCore.*Microsoft.Extensions.*System.Net.Http.Json 包引用的 Version 属性更新到 5.0.0 或更高版本。 例如:

<ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.6" />
-    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.6">
-    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.1.6" />
-    <PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
+    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="5.0.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0">
+    <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
+    <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>

更新 Docker 映像

对于使用 Docker 的应用,请更新 Dockerfile FROM 语句和脚本。 使用包含 ASP.NET Core 5.0 运行时的基础映像。 请考虑 ASP.NET Core 3.1 和 5.0 之间的以下 docker pull 命令差异:

- docker pull mcr.microsoft.com/dotnet/core/aspnet:3.1
+ docker pull mcr.microsoft.com/dotnet/aspnet:5.0

在迁移到“.NET”作为产品名称的过程中,Docker 映像将从 mcr.microsoft.com/dotnet/core 存储库移动到 mcr.microsoft.com/dotnet。 有关详细信息,请参阅 dotnet/dotnet-docker#1939

ASP.NET Core MVC 和 Razor Pages 中的模型绑定更改

日期/时间值作为 UTC 时间进行模型绑定

在 ASP.NET Core 3.1 及更早版本中,DateTime 值作为本地时间进行模型绑定,其中时区由服务器决定。 DateTime 值绑定自输入格式 (JSON) 并且 DateTimeOffset 值绑定作为 UTC 时区。

在 ASP.NET Core 5.0 及更高版本中,模型绑定将 DateTime 值与 UTC 时区一致地绑定在一起。

若要保留之前的行为,请删除 Startup.ConfigureServices 中的 DateTimeModelBinderProvider

services.AddControllersWithViews(options => 
    options.ModelBinderProviders.RemoveType<DateTimeModelBinderProvider>());

ComplexObjectModelBinderProvider \ ComplexObjectModelBinder replace ComplexTypeModelBinderProvider \ ComplexTypeModelBinder

若要添加对模型绑定 C# 9 记录类型的支持,ComplexTypeModelBinderProvider 为:

  • 注释为已过时。
  • 默认情况下不再注册。

依赖于 ModelBinderProviders 集合中存在的 ComplexTypeModelBinderProvider 的应用需要引用新的绑定器提供程序:

- var complexModelBinderProvider = options.ModelBinderProviders.OfType<ComplexTypeModelBinderProvider>();
+ var complexModelBinderProvider = options.ModelBinderProviders.OfType<ComplexObjectModelBinderProvider>();

UseDatabaseErrorPage 已过时

包含用于单个用户帐户的选项的 ASP.NET Core 3.1 模板会生成对 UseDatabaseErrorPage 的调用。 UseDatabaseErrorPage 现已过时,应替换为以下代码中所示的 AddDatabaseDeveloperPageExceptionFilterUseMigrationsEndPoint 的组合:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
+   services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
+       app.UseMigrationsEndPoint();
-       app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

有关详细信息,请参阅此 GitHub 问题

ASP.NET Core 模块 (ANCM)

如果在安装 Visual Studio 时未选择 ASP.NET Core 模块 (ANCM) 组件,或者系统上安装了 ANCM 的早期版本,请下载最新的 .NET Core 托管捆绑包安装程序(直接下载)并运行该安装程序。 有关详细信息,请参阅托管捆绑包

影响某些 NuGet 包的包引用更改

将 dotnet/extensions 内容迁移到 dotnet/runtime 和 dotnet/aspnetcore (aspnet/Announcements #411) 中所述,通过将某些 Microsoft.Extensions.* NuGet 包从 dotnet/extensions 存储库迁移到 dotnet/runtime,可将打包更改应用于某些已迁移的包。 这些更改通常会导致 .NET API 的命名空间更改。

若要进一步研究迁移到 5.0 时应用命名空间更改的 API,请使用 .NET API 浏览器

迁移 Microsoft.Identity.Web

以下 Wiki 页面介绍了如何将 Microsoft.Identity.Web 从 ASP.NET Core 3.1 迁移到 5.0:

以下教程还介绍了迁移:

查看中断性变更

有关从 .NET Core 3.1 迁移到 .NET 5.0 中断性变更的信息,请参阅从版本 3.1 迁移到 5.0 的中断性变更。 ASP.NET Core 和 Entity Framework Core 也包含在列表中。