- 概述
- 新增功能
- 基础知识
- 测试、调试和疑难解答
- 低版本升级迁移
从 ASP.NET Core 1.x 迁移到 2.0
作者:Scott Addie
本文演示如何将现有 ASP.NET Core 1.x 项目更新到 ASP.NET Core 2.0。 通过将应用程序迁移到 ASP.NET Core 2.0,可利用大量新功能和改进功能。
现有 ASP.NET Core 1.x 应用程序基于版本特定的项目模板。 随着 ASP.NET Core 框架不断演变,其中的项目模板和起始代码也在变化。 除了更新 ASP.NET Core 框架外,还需要为应用程序更新代码。
先决条件
请参阅 ASP.NET Core 入门。
更新目标框架名字对象 (TFM)
面向 .NET Core 的项目需使用大于或等于 .NET Core 2.0 版本的 TFM。 在“.csproj”文件中搜索 <TargetFramework>
节点,并将其内部文本替换为 netcoreapp2.0
:
<TargetFramework>netcoreapp2.0</TargetFramework>
面向 .NET Framework 的项目需使用大于或等于 .NET Framework 4.6.1 版本的 TFM。 在“.csproj”文件中搜索 <TargetFramework>
节点,并将其内部文本替换为 net461
:
<TargetFramework>net461</TargetFramework>
备注
相比于 .NET Core 1.x,.NET Core 2.0 提供更多的外围应用。 如果仅因为 .NET Core 1.x 中缺少 API 而要面向 .NET Framework,则定向于 .NET Core 2.0 可能有用。
如果项目文件包含 <RuntimeFrameworkVersion>1.{sub-version}</RuntimeFrameworkVersion>
,请参阅此 GitHub 问题。
在 global.json 中更新 .NET Core SDK 版本
如果解决方案依靠 global.json 文件来定向于特定 .NET Core SDK 版本,请更新其 version
属性以使用计算机上安装的 2.0 版本:
{ "sdk": { "version": "2.0.0" } }
更新包引用
1.x 项目中的“.csproj”文件列出了该项目使用的每个 NuGet 包 。
在面向 .NET Core 2.0 的 ASP.NET Core 2.0 项目中,“.csproj”文件中的单个 metapackage 引用将替换包的集合 :
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" /> </ItemGroup>
该元包中具备 ASP.NET Core 2.0 和 Entity Framework Core 2.0 的所有功能。
面向 .NET Framework 的 ASP.NET Core 2.0 项目应继续引用单个 NuGet 包。 将每个 <PackageReference />
节点的 Version
特性更新至 2.0.0。
例如,下述列表列出了面向 .NET Framework 的典型 ASP.NET Core 2.0 项目中使用的 <PackageReference />
节点:
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" /> <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" /> </ItemGroup>
更新 .NET Core CLI 工具
在“.csproj”文件中,将每个 <DotNetCliToolReference />
节点的 Version
特性更新至 2.0.0 。
例如,下述列表列出了面向 .NET Core 2.0 的典型 ASP.NET Core 2.0 项目中使用的 CLI 工具:
<ItemGroup> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> </ItemGroup>
重命名“包目标回退”属性
1.x 项目的“.csproj”文件使用了 PackageTargetFallback
节点和变量 :
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
将节点和变量重命名为 AssetTargetFallback
:
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
更新 Program.cs 中的 Main 方法
在 1.x 项目中,“Program.cs”的 Main
方法如下所示 :
using System.IO; using Microsoft.AspNetCore.Hosting; namespace AspNetCoreDotNetCore1App { public class Program { public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .UseApplicationInsights() .Build(); host.Run(); } } }
在 2.0 项目中,简化了“Program.cs”的 Main
方法 :
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; namespace AspNetCoreDotNetCore2App { public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } }
强烈建议采用新的 2.0 模式,Entity Framework (EF) Core 迁移等产品功能需要此模式才能正常运行。 例如,从“包管理器控制台”窗口运行 Update-Database
,或从命令行(位于转换为 ASP.NET Core 2.0 的项目上)运行 dotnet ef database update
时,都会生成以下错误:
Unable to create an object of type '<Context>'. Add an implementation of 'IDesignTimeDbContextFactory<Context>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
添加配置提供程序
在 1.x 项目中,已通过 Startup
构造函数将配置提供程序添加到了某个应用。 涉及的步骤包括创建 ConfigurationBuilder
实例、加载适用的提供程序(环境变量、应用设置等)以及初始化 IConfigurationRoot
的成员。
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); if (env.IsDevelopment()) { builder.AddUserSecrets<Startup>(); } builder.AddEnvironmentVariables(); Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; }
上例使用 psettings.json 以及任何与 IHostingEnvironment.EnvironmentName
属性匹配的 appsettings.<EnvironmentName>.json 文件中的配置设置加载 Configuration
成员 。 这些文件所在位置与 Startup.cs 的路径相同。
在 2.0 项目中,样板配置代码会继承在幕后运行的 1.x 代码。 例如,启动时就加载环境变量和应用设置。 等效的 Startup.cs 代码减少到 IConfiguration
初始化设置并包括插入的实例:
public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; }
若要删除由 WebHostBuilder.CreateDefaultBuilder
添加的默认提供程序,请对 ConfigureAppConfiguration
内的 IConfigurationBuilder.Sources
属性调用 Clear
方法。 若要添加回提供程序,请使用 Program.cs 中的 ConfigureAppConfiguration
方法 :
public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .ConfigureAppConfiguration((hostContext, config) => { // delete all default configuration providers config.Sources.Clear(); config.AddJsonFile("myconfig.json", optional: true); }) .Build();
若要查看上一代码片段中 CreateDefaultBuilder
方法使用的配置,请参阅此处。
有关详细信息,请参阅 ASP.NET Core 中的配置。
移动数据库初始化代码
在 1.x 项目中使用 EF Core 1.x(类似 dotnet ef migrations add
的命令)执行下列任务:
- 实例化
Startup
实例 - 调用
ConfigureServices
方法,为所有服务注册依赖关系注入(包括DbContext
类型) - 执行其必要任务
在 2.0 项目中使用 EF Core 2.0,调用 Program.BuildWebHost
以获取应用程序服务。 与 1.x 不同,这有调用 Startup.Configure
的副作用。 如果 1.x 应用在其 Configure
方法中调用了数据库初始化代码,可能出现意外问题。 例如,如果数据库尚不存在,种子设定代码将在 EF Core 迁移命令执行前运行。 如果数据库尚不存在,此问题将导致 dotnet ef migrations list
命令失败。
请考虑在 Startup.cs 的 Configure
方法中使用以下 1.x 种子初始化代码。
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); SeedData.Initialize(app.ApplicationServices);
在 2.0 项目中,将 SeedData.Initialize
调用移动到 Program.cs 的 Main
方法:
var host = BuildWebHost(args); using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; try { // Requires using RazorPagesMovie.Models; SeedData.Initialize(services); } catch (Exception ex) { var logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(ex, "An error occurred seeding the DB."); } } host.Run();
从 2.0 开始,BuildWebHost
只应用于生成和配置 Web 主机。 有关运行应用程序的所有内容都应在 BuildWebHost
外部处理 — 通常是在 Program.cs 的 Main
方法中 。
查看 Razor 视图编译设置
加快应用程序启动速度和缩小已发布的捆绑包至关重要。 为此,ASP.NET Core 2.0 中默认启用 Razor 视图编译。
无需再将 MvcRazorCompileOnPublish
属性设置为 true。 若不禁用视图编译,可能会从“.csproj”文件中删除此属性 。
以 .NET Framework 为目标时,仍需显式引用“.csproj”文件中的 Microsoft.AspNetCore.Mvc.Razor.ViewCompilation NuGet 包 :
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />
依靠 Application Insights“启动”功能
能够轻松设置应用程序性能检测非常重要。 现可依靠 Visual Studio 2017 工具中推出的新的 Application Insights“启动”功能。
Visual Studio 2017 中创建的 ASP.NET Core 1.1 项目默认添加 Application Insights。 若不直接使用 Application Insights SDK,则除了执行“Program.cs”和“Startup.cs”,还请执行以下步骤 :
如果定目标到 .NET Core,请从 .csproj 文件中删除以下
<PackageReference />
节点:<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
如果定目标到 .NET Core,请从 Program.cs 中删除
UseApplicationInsights
扩展方法调用:public static void Main(string[] args) { var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .UseApplicationInsights() .Build(); host.Run(); }
从“_Layout.cshtml”中删除 Application Insights 客户端 API 调用 。 它会比较以下两行代码:
@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet @Html.Raw(JavaScriptSnippet.FullScript)
若要直接使用 Application Insights SDK,请继续此操作。 2.0 元包中具备最新版本的 Application Insights,因此如果引用较旧版本,将出现包降级错误。
采用身份验证/标识改进
ASP.NET Core 2.0 具有新的身份验证模型和大量针对 ASP.NET Core 标识的重大更改。 如果在启用个人用户帐户的情况下创建了项目,或者已手动添加身份验证或标识,请参阅将身份验证和标识迁移到 ASP.NET Core 2.0。