天天看點

從 ASP.NET Core 1.x 遷移到 2.0

本文示範如何将現有 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

 :

XML複制

<TargetFramework>netcoreapp2.0</TargetFramework>
           

面向 .NET Framework 的項目需使用大于或等于 .NET Framework 4.6.1 版本的 TFM。 在“.csproj”檔案中搜尋 

<TargetFramework>

 節點,并将其内部文本替換為 

net461

 :

XML複制

<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 版本 :

JSON複制

{ "sdk": { "version": "2.0.0" } }

更新包引用

1.x 項目中的“.csproj”檔案列出了該項目使用的每個 NuGet 包 。

在面向 .NET Core 2.0 的 ASP.NET Core 2.0 項目中,“.csproj”檔案中的單個 metapackage 引用将替換包的集合 :

XML複制

<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 />

 節點:

XML複制

<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 工具:

XML複制

<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

 節點和變量 :

XML複制

<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
           

将節點和變量重命名為 

AssetTargetFallback

XML複制

<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
           

更新 Program.cs 中的 Main 方法

在 1.x 項目中,“Program.cs”的 

Main

 方法如下所示 :

C#複制

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

 方法 :

C#複制

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

 的成員。

C#複制

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

 初始化設定并包括插入的執行個體:

C#複制

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

 的指令)執行下列任務:

  1. 執行個體化 

    Startup

     執行個體
  2. 調用 

    ConfigureServices

     方法,為所有服務注冊依賴關系注入(包括 

    DbContext

     類型)
  3. 執行其必要任務

在 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 種子初始化代碼。

C#複制

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

SeedData.Initialize(app.ApplicationServices);
           

在 2.0 項目中,将 

SeedData.Initialize

 調用移動到 Program.cs 的 

Main

 方法:

C#複制

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 包 :

XML複制

<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”,還請執行以下步驟 :

  1. 如果定目标到 .NET Core,請從 .csproj 檔案中删除以下 

    <PackageReference />

     節點:

    XML複制

    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
               
  2. 如果定目标到 .NET Core,請從 Program.cs 中删除 

    UseApplicationInsights

     擴充方法調用:

    C#複制

    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .Build();
    
        host.Run();
    }
               
  3. 從“_Layout.cshtml”中删除 Application Insights 用戶端 API 調用 。 它會比較以下兩行代碼:

    CSHTML複制

    @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。

繼續閱讀