从 ASP.NET Core 2.0 迁移到 2.1
有关 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 版本
更新项目文件:
- 通过将项目文件更新为
<TargetFramework>netcoreapp2.1</TargetFramework>
,将目标框架更改为 .NET Core 2.1。 - 将
Microsoft.AspNetCore.All
的包引用替换为Microsoft.AspNetCore.App
的包引用。 可能需要添加已从Microsoft.AspNetCore.All
中删除的依赖项。 有关详细信息,请参阅 ASP.NET Core 2.0 的 Microsoft.AspNetCore.All 元包和 ASP.NET Core 的 Microsoft.AspNetCore.App 元包。 - 删除
Microsoft.AspNetCore.App
的包引用中的“Version”特性。 使用<Project Sdk="Microsoft.NET.Sdk.Web">
的项目不需要设置版本。 版本由目标框架隐含,并且选择的版本会最符合 ASP.NET Core 2.1 的工作方式。 有关详细信息,请参阅适用于面向共享框架的项目的规则部分。 - 对于面向 .NET Framework 的应用,将每个包引用更新为 2.1。
- 对于以下包,删除对 <DotNetCliToolReference> 元素的引用。 默认情况下,这些工具已捆绑在 .NET CLI 中,无需单独安装。
- Microsoft.DotNet.Watcher.Tools (
dotnet watch
) - Microsoft.EntityFrameworkCore.Tools.DotNet (
dotnet ef
) - Microsoft.Extensions.Caching.SqlConfig.Tools (
dotnet sql-cache
) - Microsoft.Extensions.SecretManager.Tools (
dotnet user-secrets
)
- Microsoft.DotNet.Watcher.Tools (
- 可选:可以删除
Microsoft.VisualStudio.Web.CodeGeneration.Tools
的 <DotNetCliToolReference> 元素。 可以通过运行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 |
将 Dockerfile 中的 FROM
行更改为使用上表的 2.1 列中的新映像名称和标记。 有关详细信息,请参阅从 aspnetcore docker 存储库迁移到 dotnet。
为利用 ASP.NET Core 2.1 中推荐的基于代码的新习惯用语而进行的更改
对 Main 的更改
下图显示了对模板生成的 Program.cs
文件进行的更改。
上图显示了 2.0 版本,其中删除内容以红色显示。
下图显示了 2.1 代码。 绿色代码替换了 2.0 版本:
下面的代码显示了 2.1 版本的 Program.cs
:
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 以支持新的集成测试基础结构。
对 Startup 的更改
下面的代码演示对 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 中的 GDPR 支持(适用于
CookiePolicyOptions
和UseCookiePolicy
)。 - HTTP 严格传输安全协议 (HSTS)(适用于
UseHsts
)。 - 要求使用 HTTPS(适用于
UseHttpsRedirection
)。 - SetCompatibilityVersion(适用于
SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
)。
对验证码的更改
ASP.NET Core 2.1 提供 ASP.NET Core Identity 作为 Razor 类库 (RCL)。
默认 2.1 Identity UI 当前不提供高于 2.0 版本的重要新功能。 可选择将 Identity 替换为 RCL 包。 将模板生成的 Identity 代码替换为 RCL 版本的优点包括:
- 许多文件移出了源树。
- 任何 bug 修补程序或 Identity 的新功能都包含在 Microsoft.AspNetCore.App 元包中。
Microsoft.AspNetCore.App
更新时,你会自动获得更新的 Identity。
如果对模板生成的 Identity 代码进行了不平常的更改:
- 以上优点可能无法证明应转换为 RCL 版本。
- 你可以保留 ASP.NET Core 2.0 Identity 代码,它完全受支持。
Identity 2.1 公开具有 Identity
区域的终结点。 例如,下表显示了从 2.0 更改为 2.1 的 Identity 终结点的示例:
2.0 URL | 2.1 URL |
---|---|
/Account/Login | /Identity/Account/Login |
/Account/Logout | /Identity/Account/Logout |
/Account/Manage | /Identity/Account/Manage |
其代码使用 Identity 并将 2.0 Identity UI 替换为 2.1 Identity 库的应用程序需要考虑 Identity URL 将 /Identity
段置于 URI 前面。 处理新 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 IdentityRazor 类库。 你可以为修改的任何 Identity UI 代码生成代码和 UI。 将代码更改应用于新搭建基架的 UI 代码。
- 删除现有的 Identity 2.0 代码,并使用“替代所有文件”选项在项目中设置 Identity 的基架。
将 Identity 2.0 UI 替换为 Identity 2.1 Razor 类库
此部分概述将 ASP.NET Core 2.0 模板生成的 Identity 代码替换为 ASP.NET Core IdentityRazor 类库的步骤。 以下步骤适用于 Razor Pages 项目,不过适用于 MVC 项目的方法是类似的。
- 验证项目文件是否更新为使用 2.1 版本
- 删除以下文件夹及其中的所有文件:
- Controllers
- Pages/Account/
- 扩展
- 生成项目。
- 在项目中设置 Identity 的基架:
- 选择项目现有 _Layout.cshtml 文件。
- 选择“数据上下文类”右侧的 + 图标。 接受默认名称。
- 选择“添加”以创建新的数据上下文类。 搭建基架需要创建新的数据上下文。 你会在下一部分中删除新的数据上下文。
为 Identity 搭建基架之后的更新
在 Areas/Identity/Data/ 文件夹中删除 Identity 基架生成的
IdentityDbContext
派生类。删除
Areas/Identity/IdentityHostingStartup.cs
。更新 _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.0 更改为 jquery.validate/1.17.0。
新文件
添加了以下文件:
Privacy.cshtml
Privacy.cshtml.cs
有关以上文件的信息,请参阅 ASP.NET Core 中的 GDPR 支持。
对 MVC 项目 Razor 文件的更改
布局文件
Layout.cshtml
文件具有以下更改:
- 添加了
<partial name="_CookieConsentPartial" />
。 - jQuery 从 2.2.0 更改为 3.3.1
_ValidationScriptsPartial.cshtml
jquery.validate/1.14.0 更改为 jquery.validate/1.17.0
新文件和操作方法
添加了以下内容:
Views/Home/Privacy.cshtml
Privacy
操作方法已添加到 Home 控制器。
有关以上文件的信息,请参阅 ASP.NET Core 中的 GDPR 支持。
对 launchSettings.json 文件的更改
由于 ASP.NET Core 应用现在默认使用 HTTPS,因此 Properties/launchSettings.json
有所更改。
以下 JSON 显示了早期 2.0 模板生成的 launchSettings.json
文件:
{
"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.json
文件:
{
"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-Ranges 标头。 若要启用 Accept-Ranges
标头,请将 EnableRangeProcessing 设置为 true
。
ControllerBase.File 和 PhysicalFile 范围标头
默认情况下,以下 ControllerBase 方法不再处理 Accept-Ranges 标头:
若要启用 Accept-Ranges
标头,请将 EnableRangeProcessing
参数设置为 true
。
ASP.NET Core 模块 (ANCM)
如果在安装 Visual Studio 时未选择 ASP.NET Core 模块 (ANCM) 组件,或者系统上安装了 ANCM 的早期版本,请下载最新的 .NET Core 托管捆绑包安装程序(直接下载)并运行该安装程序。 有关详细信息,请参阅托管捆绑包。