从 ASP.NET Core 2.0 到 2.1 迁移Migrate from ASP.NET Core 2.0 to 2.1

本文内容

作者:Rick Anderson

有关 ASP.NET Core 2.1 中的新功能的概述,请参阅ASP.NET Core 2.1 的新增功能。

本文:

  • 介绍如何将 ASP.NET Core 2.0 应用迁移到 2.1 版的基础知识。
  • 提供对 ASP.NET Core web 应用程序模板的更改的概述。

若要大致了解2.1 中的更改,请执行以下操作:

  • 创建名为 WebApp1 的 ASP.NET Core 2.0 web 应用。
  • 提交源代码管理系统中的 WebApp1。
  • 删除 WebApp1 并创建名为 WebApp1 放在同一位置的 ASP.NET Core 2.1 web 应用。
  • 查看2.1 版本中的更改。

本文提供了有关迁移到 ASP.NET Core 2.1 的概述。它不包含迁移到版本2.1 所需的所有更改的完整列表。某些项目可能需要更多步骤,具体取决于创建项目时选择的选项以及对项目所做的修改。

更新项目文件以使用 2.1 版本Update the project file to use 2.1 versions

更新项目文件:

  • 通过将项目文件更新为 <TargetFramework>netcoreapp2.1</TargetFramework>,将目标框架更改为 .NET Core 2.1。
  • 使用 Microsoft.AspNetCore.App的包引用替换 Microsoft.AspNetCore.All 的包引用。可能需要添加已从 Microsoft.AspNetCore.All中删除的依赖项。有关详细信息,请参阅 ASP.NET Core 2.0 的 Microsoft.AspNetCore.All 元包ASP.NET Core 的 Microsoft.AspNetCore.App 元包
  • 删除包对 Microsoft.AspNetCore.App的 "版本" 属性。使用 <Project Sdk="Microsoft.NET.Sdk.Web"> 的项目不需要设置版本。版本由目标框架隐含,并选择最符合 ASP.NET Core 2.1 的工作方式。有关详细信息,请参阅面向共享框架的项目的规则部分。
  • 对于面向 .NET Framework 的应用,将每个包引用更新为2.1。
  • 对于以下包,删除对 元素的引用。默认情况下,这些工具在 .NET Core CLI 中捆绑在一起,无需单独安装。
    • DotNet (dotnet watch
    • Microsoft.entityframeworkcore. DotNet (dotnet ef
    • SqlConfig (dotnet sql-cache)(& e)
    • SecretManager (dotnet user-secrets
  • 可选:可以删除 Microsoft.VisualStudio.Web.CodeGeneration.Tools 元素。可以通过运行 dotnet tool install -g dotnet-aspnet-codegenerator将此工具替换为全局安装的版本。
  • 对于2.1,建议使用Razor 类库作为分发 razor 文件的解决方案。如果你的应用使用嵌入的视图,或者依赖于 Razor 文件的运行时编译,请将 <CopyRefAssembliesToPublishDirectory>true</CopyRefAssembliesToPublishDirectory> 添加到项目文件中的 <PropertyGroup>

    以下标记显示模板生成的2.0 项目文件:
  1. <Project Sdk="Microsoft.NET.Sdk.Web">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp2.0</TargetFramework>
  4. <UserSecretsId>aspnet-{Project Name}-{GUID}</UserSecretsId>
  5. </PropertyGroup>
  6. <ItemGroup>
  7. <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
  8. <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.3" PrivateAssets="All" />
  9. <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.4" PrivateAssets="All" />
  10. </ItemGroup>
  11. <ItemGroup>
  12. <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.3" />
  13. <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.2" />
  14. <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.4" />
  15. </ItemGroup>
  16. </Project>

以下标记显示模板生成的2.1 项目文件:

  1. <Project Sdk="Microsoft.NET.Sdk.Web">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp2.1</TargetFramework>
  4. <UserSecretsId>aspnet-{Project Name}-{GUID}</UserSecretsId>
  5. </PropertyGroup>
  6. <ItemGroup>
  7. <PackageReference Include="Microsoft.AspNetCore.App" />
  8. <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" PrivateAssets="All" />
  9. </ItemGroup>
  10. </Project>

面向共享框架的项目的规则Rules for projects targeting the shared framework

共享框架是不在应用的文件夹中的一组程序集(.dll 文件)。必须将共享框架安装在计算机上才能运行应用。有关详细信息,请参阅共享框架

ASP.NET Core 2.1 包括以下共享框架:

包引用指定的版本是所需的最低版本。例如,引用这些包的2.1.1 版本的项目不会在安装了2.1.0 运行时的计算机上运行。

面向共享框架的项目的已知问题:

  • .NET Core 2.1.300 SDK (第一条包含在 Visual Studio 15.6 中)将 Microsoft.AspNetCore.App 的隐式版本设置为2.1.0,这会导致与 Entity Framework Core 2.1.1 发生冲突。建议的解决方案是将 .NET Core SDK 升级到2.1.301 或更高版本。有关详细信息,请参阅与 AspNetCore 共享依赖项的包。应用无法引用修补程序版本

  • 必须使用 Microsoft.AspNetCore.AllMicrosoft.AspNetCore.App 的所有项目都应在项目文件中添加包的包引用,即使它们包含使用 Microsoft.AspNetCore.AllMicrosoft.AspNetCore.App的其他项目的项目引用。

示例:

更新为 2.1 Docker 映像Update to the 2.1 Docker images

在 ASP.NET Core 2.1 中,迁移到dotnet/Dotnet GitHub 存储库的 Docker 映像。下表显示了 Docker 映像和标记更改:

2.02.1
microsoft/aspnetcore:2。0microsoft/dotnet:2.1-aspnetcore-runtime
microsoft/aspnetcore:2。0microsoft/dotnet:2.1-sdk

更改Dockerfile中的 FROM 行,以使用上表的2.1 列中的新映像名称和标记。有关详细信息,请参阅从 aspnetcore docker 存储库迁移到 dotnet

若要利用 ASP.NET Core 2.1 中建议的新基于代码的惯例的更改Changes to take advantage of the new code-based idioms that are recommended in ASP.NET Core 2.1

对 Main 的更改Changes to Main

下图显示了对模板生成的Program.cs文件所做的更改。

旧版本差异

上图显示了2.0 版本,其中删除内容以红色显示。

下图显示了2.1 代码。绿色代码替换了2.0 版本:

新版本差异

以下代码显示了2.1 版本的Program.cs

  1. namespace WebApp1
  2. {
  3. public class Program
  4. {
  5. public static void Main(string[] args)
  6. {
  7. CreateWebHostBuilder(args).Build().Run();
  8. }
  9. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  10. WebHost.CreateDefaultBuilder(args)
  11. .UseStartup<Startup>();
  12. }
  13. }

MainCreateWebHostBuilder替换对 BuildWebHost 的调用。添加了IWebHostBuilder以支持新的集成测试基础结构

对启动的更改Changes to Startup

下面的代码演示对2.1 模板生成的代码所做的更改。除已删除 UseBrowserLink 之外,所有更改都是新添加的代码:

  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.DependencyInjection;
  7. namespace WebApp1
  8. {
  9. public class Startup
  10. {
  11. public Startup(IConfiguration configuration)
  12. {
  13. Configuration = configuration;
  14. }
  15. public IConfiguration Configuration { get; }
  16. public void ConfigureServices(IServiceCollection services)
  17. {
  18. services.Configure<CookiePolicyOptions>(options =>
  19. {
  20. // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  21. options.CheckConsentNeeded = context => true;
  22. options.MinimumSameSitePolicy = SameSiteMode.None;
  23. });
  24. services.AddMvc()
  25. .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  26. }
  27. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  28. {
  29. if (env.IsDevelopment())
  30. {
  31. app.UseDeveloperExceptionPage();
  32. }
  33. else
  34. {
  35. app.UseExceptionHandler("/Error");
  36. app.UseHsts();
  37. }
  38. app.UseHttpsRedirection();
  39. app.UseStaticFiles();
  40. app.UseCookiePolicy();
  41. // If the app uses Session or TempData based on Session:
  42. // app.UseSession();
  43. app.UseMvc();
  44. }
  45. }
  46. }

中详细介绍了前面的代码更改:

对身份验证代码的更改Changes to authentication code

ASP.NET Core 2.1 提供作为Razor 类库(RCL)的ASP.NET Core 标识

默认的2.1 标识 UI 当前不提供超过2.0 版本的重要新功能。用 RCL 包替换标识是可选的。将模板生成的标识代码替换为 RCL 版本的优点包括:

  • 许多文件已移出源树。
  • AspNetCore 元包中包含任何 bug 修复或用于标识的新功能。更新 Microsoft.AspNetCore.App 时,会自动获取已更新的标识。

如果对模板生成的标识代码进行了不重要的更改:

  • 上述优点可能不会将转换为 RCL 版本。
  • 你可以将 ASP.NET Core 2.0 标识代码,完全支持。

标识2.1 公开 Identity 区域中的终结点。例如,下表显示了从2.0 更改为2.1 的标识终结点的示例:

2.0 URL2.1 URL
/Account/Login/Identity/Account/Login
/Account/Logout/Identity/Account/Logout
/Account/Manage/Identity/Account/Manage

如果应用程序的代码使用标识,并用2.1 标识库替换2.0 标识 UI,则需要将标识 Url 包含在 Uri 前面 /Identity 段。处理新标识终结点的一种方法是设置重定向,例如从 /Account/Login/Identity/Account/Login

将标识更新到版本2。1Update Identity to version 2.1

以下选项可用于将标识更新为2.1。

  • 使用标识 UI 2.0 代码,不进行任何更改。完全支持使用标识 UI 2.0 代码。如果对生成的标识代码进行了重大更改,则这是一种很好的方法。
  • 删除现有的标识2.0 代码,并将基架标识导入到项目中。你的项目将使用ASP.NET Core IdentityRazor类库。你可以为你修改的任何标识 UI 代码生成代码和 UI。将代码更改应用于新的基架 UI 代码。
  • 将现有的标识2.0 代码和基架标识删除到你的项目中,其中包含替代所有文件的选项。

将标识 2.0 UI 替换为标识 2.1 Razor 类库Replace Identity 2.0 UI with the Identity 2.1 Razor Class Library

本部分概述了将 ASP.NET Core 2.0 模板生成的标识代码替换为ASP.NET Core IdentityRazor 类库的步骤。以下步骤适用于 Razor Pages 项目,但 MVC 项目的方法类似。

  • 验证是否已更新项目文件以使用2.1 版本
  • 删除以下文件夹及其所有文件:
    • Controllers
    • Pages/Account/
    • 扩展
  • 生成项目。
  • 标识基架到你的项目中:
    • 选择 _布局 cshtml文件中退出的项目。
    • 选择数据上下文类右侧的 + 图标。接受默认名称。
    • 选择 "添加" 以创建新的数据上下文类。需要为基架创建新的数据上下文。在下一部分中,将删除新的数据上下文。

在基架标识后更新Update after scaffolding Identity

  • 删除在区域/标识/数据/ 文件夹中 IdentityDbContext 派生类生成的标识 scaffolder。

  • 删除区域/标识/IdentityHostingStartup

  • 更新 _loginpartial.cshtml文件:

    • pages/_loginpartial.cshtml移到pages/Shared/_loginpartial.cshtml
    • asp-area="Identity" 添加到窗体和定位点链接。
    • <form /> 元素更新为 <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
      下面的代码显示更新后的 _loginpartial.cshtml文件:
  1. @using Microsoft.AspNetCore.Identity
  2. @inject SignInManager<ApplicationUser> SignInManager
  3. @inject UserManager<ApplicationUser> UserManager
  4. @if (SignInManager.IsSignedIn(User))
  5. {
  6. <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
  7. <ul class="nav navbar-nav navbar-right">
  8. <li>
  9. <a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
  10. </li>
  11. <li>
  12. <button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
  13. </li>
  14. </ul>
  15. </form>
  16. }
  17. else
  18. {
  19. <ul class="nav navbar-nav navbar-right">
  20. <li><a asp-area="Identity" asp-page="/Account/Register">Register</a></li>
  21. <li><a asp-area="Identity" asp-page="/Account/Login">Log in</a></li>
  22. </ul>
  23. }

使用以下代码更新 ConfigureServices

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddDbContext<ApplicationDbContext>(options =>
  4. options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  5. services.AddDefaultIdentity<ApplicationUser>()
  6. .AddEntityFrameworkStores<ApplicationDbContext>()
  7. .AddDefaultTokenProviders();
  8. services.AddMvc();
  9. // Register no-op EmailSender used by account confirmation and password reset
  10. // during development
  11. services.AddSingleton<IEmailSender, EmailSender>();
  12. }

对 Razor Pages 项目 Razor 文件的更改Changes to Razor Pages projects Razor files

布局文件The layout file

  • pages/_layout转换为Pages/Shared/_layout

  • 在 "区域/标识/页/_viewstart.cshtml中,将 Layout = "/Pages/_Layout.cshtml" 更改为" Layout = "/Pages/Shared/_Layout.cshtml""。

  • _的布局 cshtml文件具有以下更改:

_ValidationScriptsPartial_ValidationScriptsPartial.cshtml

  • Pages/_ValidationScriptsPartial将移到pages/Shared/_ValidationScriptsPartial
  • jquery . validate/1.14.0 /1.17.0

新文件New files

添加了以下文件:

  • Privacy.cshtml
  • Privacy.cshtml.cs

有关上述文件的信息,请参阅ASP.NET Core 中的 GDPR 支持

对 MVC 项目 Razor 文件的更改Changes to MVC projects Razor files

布局文件The layout file

布局 cshtml文件具有以下更改:

  • 添加 <partial name="_CookieConsentPartial" />
  • 从2.2.0 到3.3.1 的 jQuery 更改

_ValidationScriptsPartial_ValidationScriptsPartial.cshtml

jquery. validate/1.14.0__的更改

新文件和操作方法New files and action methods

添加了以下内容:

  • 视图/Home/私密
  • Privacy 操作方法将添加到 Home 控制器。

有关上述文件的信息,请参阅ASP.NET Core 中的 GDPR 支持

对 Launchsettings.json 文件的更改Changes to the launchSettings.json file

由于 ASP.NET Core 应用现在默认使用 HTTPS,因此Properties/launchsettings.json文件已更改。

以下 JSON 显示了前面的2.0 模板生成的launchsettings.json文件:

  1. {
  2. "iisSettings": {
  3. "windowsAuthentication": false,
  4. "anonymousAuthentication": true,
  5. "iisExpress": {
  6. "applicationUrl": "http://localhost:1799/",
  7. "sslPort": 0
  8. }
  9. },
  10. "profiles": {
  11. "IIS Express": {
  12. "commandName": "IISExpress",
  13. "launchBrowser": true,
  14. "environmentVariables": {
  15. "ASPNETCORE_ENVIRONMENT": "Development"
  16. }
  17. },
  18. "WebApp1": {
  19. "commandName": "Project",
  20. "launchBrowser": true,
  21. "environmentVariables": {
  22. "ASPNETCORE_ENVIRONMENT": "Development"
  23. },
  24. "applicationUrl": "http://localhost:1798/"
  25. }
  26. }
  27. }

以下 JSON 显示了新的2.1 模板生成的launchsettings.json文件:

  1. {
  2. "iisSettings": {
  3. "windowsAuthentication": false,
  4. "anonymousAuthentication": true,
  5. "iisExpress": {
  6. "applicationUrl": "http://localhost:39191",
  7. "sslPort": 44390
  8. }
  9. },
  10. "profiles": {
  11. "IIS Express": {
  12. "commandName": "IISExpress",
  13. "launchBrowser": true,
  14. "environmentVariables": {
  15. "ASPNETCORE_ENVIRONMENT": "Development"
  16. }
  17. },
  18. "WebApp1": {
  19. "commandName": "Project",
  20. "launchBrowser": true,
  21. "applicationUrl": "https://localhost:5001;http://localhost:5000",
  22. "environmentVariables": {
  23. "ASPNETCORE_ENVIRONMENT": "Development"
  24. }
  25. }
  26. }
  27. }

有关详细信息,请参阅 强制实施 HTTPS 在 ASP.NET Core

重大更改Breaking changes

FileResult 范围标头FileResult Range header

默认情况下,FileResult 不再处理Accept 范围标头。若要启用 Accept-Ranges 标头,请将 EnableRangeProcessing 设置为 "true"。

ControllerBase 和 PhysicalFile 范围标头ControllerBase.File and PhysicalFile Range header

默认情况下,以下 ControllerBase 方法不再处理Accept 范围标头:

若要启用 Accept-Ranges 标头,请将 EnableRangeProcessing 参数设置为 true

其他更改Additional changes