从 ASP.NET Core 2.0 迁移到 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 中的更改的一种快速方法为:

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

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

更新项目文件以使用 2.1 版本

更新项目文件:

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

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

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <UserSecretsId>aspnet-{Project Name}-{GUID}</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.3" PrivateAssets="All" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.4" PrivateAssets="All" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.3" />
    <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.2" />
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.4" />
  </ItemGroup>
</Project>

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

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

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <UserSecretsId>aspnet-{Project Name}-{GUID}</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" PrivateAssets="All" />
  </ItemGroup>

</Project>

面向共享框架的项目的规则

共享框架是不在应用的文件夹中的一组程序集(.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 或更高版本。 有关详细信息,请参阅与应用程序 共享依赖项 Microsoft.AspNetCore.App 无法引用修补程序版本

  • 必须使用 或 的所有项目都应在项目文件中为包添加包引用,即使它们包含对使用 或 的另一 Microsoft.AspNetCore.All Microsoft.AspNetCore.App 个项目的项目 Microsoft.AspNetCore.All 引用 Microsoft.AspNetCore.App

    示例:

    • MyApp 具有对 的包引用 Microsoft.AspNetCore.App
    • MyApp.Tests 具有对 的项目引用 MyApp.csproj

    将 的包引用 Microsoft.AspNetCore.App 添加到 MyApp.Tests 。 有关详细信息,请参阅 集成测试难以设置,并且可能会中断共享框架服务

更新到 2.1 Docker 映像

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

2.0 2.1
microsoft/aspnetcore:2.0 microsoft/dotnet:2.1-aspnetcore-runtime
microsoft/aspnetcore-build:2.0 microsoft/dotnet:2.1-sdk

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

对 Main 的更改

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

旧版本差异

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

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

新版本差异

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

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

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

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

对启动的更改

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

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace WebApp1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

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

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            // If the app uses Session or TempData based on Session:
            // app.UseSession();

            app.UseMvc();
        }
    }
}

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

对身份验证代码的更改

ASP.NET Core 2.1 提供 ASP.NET Core Identity (RCL Razor ) 的类库。

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

  • 许多文件已移出源树。
  • 任何 bug 修复或的新功能 Identity 都包含在 Microsoft.AspNetCore.App 元包中。 更新时,你会自动获得更新 Identity Microsoft.AspNetCore.App

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

  • 上述优点可能 不会 将转换为 RCL 版本。
  • 可以保留 ASP.NET Core 2.0 Identity 代码,它完全受支持。

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

2.0 URL 2.1 URL
/Account/Login /Identity/Account/Login
/Account/Logout /Identity/Account/Logout
/Account/Manage /Identity/Account/Manage

如果应用程序的代码使用 Identity 2.0 UI 并将其替换为 Identity 2.1 库,则应用程序需考虑 URL 在 URI 前添加 Identity Identity /Identity 段。 处理新终结点的 Identity 一种方式是设置重定向,例如从 /Account/Login/Identity/Account/Login

更新 Identity 到版本 2.1

以下选项可用于更新到 Identity 2.1。

  • 使用 Identity UI 2.0 代码,无需更改。 完全支持 Identity 使用 UI 2.0 代码。 对生成的代码进行了重大更改时,这是一个不错的 Identity 方法。
  • 删除项目 Identity 的现有 2.0 代码和 Identity 基架。 项目将使用类 ASP.NET Core Identity Razor 库。 你可以为你修改的任何 UI 代码生成代码和 UI Identity 。 将代码更改应用于新的基架 UI 代码。
  • Identity将现有的2.0 代码和 基架 Identity删除到你的项目中,其中包含 替代所有文件 的选项。

Identity用2.1 类库替换 2.0 Identity UI Razor

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

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

在基架之后更新 Identity

  • 删除 Identity IdentityDbContext 区域/ Identity /Data/ 文件夹中的 scaffolder 生成的派生类。

  • 删除 区域/ Identity / Identity HostingStartup

  • 更新 _ 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 文件:

    @using Microsoft.AspNetCore.Identity
    
    @inject SignInManager<ApplicationUser> SignInManager
    @inject UserManager<ApplicationUser> UserManager
    
    @if (SignInManager.IsSignedIn(User))
    {
        <form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })" method="post" id="logoutForm" class="navbar-right">
            <ul class="nav navbar-nav navbar-right">
                <li>
                    <a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
                </li>
                <li>
                    <button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
                </li>
            </ul>
        </form>
    }
    else
    {
        <ul class="nav navbar-nav navbar-right">
            <li><a asp-area="Identity" asp-page="/Account/Register">Register</a></li>
            <li><a asp-area="Identity" asp-page="/Account/Login">Log in</a></li>
        </ul>
    }
    

使用以下代码更新 ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<ApplicationUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();

    // Register no-op EmailSender used by account confirmation and password reset 
    // during development
    services.AddSingleton<IEmailSender, EmailSender>();
}

对 Razor Pages 项目文件的 Razor 更改

布局文件

  • Pages/ _ Layout.cshtml 移动到 Pages/Shared/ _ Layout.cshtml

  • Areas/ Identity /Pages/ _ ViewStart.cshtml 中, Layout = "/Pages/_Layout.cshtml" 将 更改为 Layout = "/Pages/Shared/_Layout.cshtml"

  • _ Layout.cshtml 文件具有以下更改:

    • <partial name="_CookieConsentPartial" /> 已添加 。 有关详细信息,请参阅 ASP.NET Core 中的 GDPR 支持
    • jQuery 从 2.2.0 更改到 3.3.1。

_ValidationScriptsPartial.cshtml

  • Pages/ _ValidationScriptsPartial.cshtml 移动到 Pages/Shared/ _ ValidationScriptsPartial.cshtml
  • jquery.validate/1.14.0jquery.validate/1.17.0 的更改

新文件

添加了以下文件:

  • Privacy.cshtml
  • Privacy.cshtml.cs

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

对 MVC 项目文件的 Razor 更改

布局文件

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

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

_ValidationScriptsPartial

jquery. validate/1.14.0 的更改

新文件和操作方法

添加了以下内容:

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

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

对文件 launchSettings.js的更改

由于 ASP.NET Core 应用现在默认使用 HTTPS,因此文件 上的属性/launchSettings.js 已更改。

以下 JSON 显示了 在文件上 生成的早期2.0 模板launchSettings.js:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:1799/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "WebApp1": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:1798/"
    }
  }
}

以下 JSON 显示了 在文件上 生成的新2.1 模板launchSettings.js:

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:39191",
      "sslPort": 44390
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "WebApp1": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

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

中断性变更

FileResult 范围标头

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

ControllerBase 和 PhysicalFile 范围标头

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

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

其他更改