作者:Scott Addie
本文将指导你完成将现有 ASP.NET Core 1.x 项目更新为 ASP.NET Core 2.0。 将应用程序迁移到 ASP.NET Core 2.0 使你能够利用 许多新功能和性能改进。
现有 ASP.NET Core 1.x 应用程序基于特定于版本的项目模板。 随着 ASP.NET 核心框架的发展,项目模板和它们中包含的初学者代码也是如此。 除了更新 ASP.NET Core 框架之外,还需要更新应用程序的代码。
先决条件
请参阅 ASP.NET Core 入门。
更新目标框架名字对象 (TFM)
面向 .NET Core 的项目应使用大于或等于 .NET Core 2.0 的版本 TFM 。 查找<TargetFramework>
节点在.csproj
文件中,并将其内部文本替换为netcoreapp2.0
:
<TargetFramework>netcoreapp2.0</TargetFramework>
面向 .NET Framework 的项目应使用大于或等于 .NET Framework 4.6.1 的版本 TFM。 在.csproj
文件中搜索<TargetFramework>
节点,并将其内部文本替换为net461
:
<TargetFramework>net461</TargetFramework>
注释
.NET Core 2.0 提供比 .NET Core 1.x 更广泛的功能范围。 如果您仅仅因为 .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"
}
}
更新包引用
.csproj
1.x 项目中的文件列出了项目使用的每个 NuGet 包。
在面向 .NET Core 2.0 的 ASP.NET Core 2.0 项目中,.csproj
文件中的单个 元包 引用可以替代一组包:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
</ItemGroup>
ASP.NET Core 2.0 和 Entity Framework Core 2.0 的所有功能都包含在元包中。
ASP.NET 面向 .NET Framework 的 Core 2.0 项目应继续引用单个 NuGet 包。 将 Version
每个 <PackageReference />
节点的属性更新为 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>
包 Microsoft.Extensions.CommandLineUtils
已 停用。 它仍然可用,但不受支持。
更新 .NET CLI 工具
在 .csproj
文件中,将 Version
每个 <DotNetCliToolReference />
节点的属性更新为 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>
重命名软件包目标回退属性
.csproj
1.x 项目的文件使用了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 模式,并且需要使用 实体框架(EF)核心迁移 等产品功能才能正常工作。 例如,从包管理器控制台窗口运行Update-Database
或从命令行运行dotnet ef database update
(在转换为 ASP.NET Core 2.0 的项目上)将生成以下错误:
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; }
前面的示例从appsettings.json
加载配置设置,并从匹配IHostingEnvironment.EnvironmentName
属性的任何appsettings.{Environment}.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 中的配置。
移动数据库初始化代码
在使用 EF Core 1.x 的项目中,命令 dotnet ef migrations add
会执行以下操作:
- 实例化
Startup
实例 - 调用
ConfigureServices
方法通过依赖注入注册所有服务(包括DbContext
类型) - 执行其必备任务
在使用 EF Core 2.0 的 2.0 项目中, Program.BuildWebHost
调用以获取应用程序服务。 与 1.x 不同,这具有调用 Startup.Configure
的额外副作用。 如果 1.x 应用在其 Configure
方法中调用了数据库初始化代码,则可能会出现意外的问题。 例如,如果数据库尚未存在,则初始化数据代码会在 EF Core 迁移命令执行之前运行。 如果数据库尚不存在,则此问题会导致 dotnet ef migrations list
命令失败。
请考虑以下 1.x 种子初始化代码在Startup.cs
的Configure
方法中:
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 开始,除了生成和配置 Web 主机之外,不建议在 BuildWebHost
中执行任何操作。 任何与运行应用程序相关的内容都应该在 BuildWebHost
外部处理,通常在 Program.cs
中的 Main
方法中进行。
查看 Razor 视图编译设置
更快的应用程序启动时间和较小的已发布捆绑包对你至关重要。 出于这些原因, Razor 视图编译 默认在 ASP.NET Core 2.0 中启用。
不再需要将 MvcRazorCompileOnPublish
属性设置为 true。 除非禁用视图编译,否则该属性可能会从 .csproj
文件中删除。
面向 .NET Framework 时,仍需显式引用 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 “亮起”功能。
默认情况下,ASP.NET Visual Studio 2017 中创建的 Core 1.1 项目添加了 Application Insights。 如果没有直接在Program.cs
和Startup.cs
环境中使用 Application Insights SDK,请执行以下步骤:
如果面向 .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,因此,如果引用较旧版本,将显示包降级错误。
采用身份验证/Identity 改进
ASP.NET Core 2.0 具有新的身份验证模型,对 ASP.NET Core Identity进行了大量重大更改。 如果您在创建项目时启用了个人用户帐户,或者您已手动添加身份验证,请参阅 迁移身份验证和 Identity 到 ASP.NET Core 2.0。