從 ASP.NET Core 2.0 移轉到 2.1

作者:Rick Anderson

如需 .NET Core 2.1 新功能的概觀,請參閱 .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>,將目標 Framework 變更為 .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"> 的專案不需要設定版本。 版本會隱含在目標 Framework 中,並加以選取以最符合 ASP.NET Core 2.1 的運作方式。 如需詳細資訊,請參閱以共用架構為目標的專案規則一節。
  • 針對以 .NET Framework 為目標的應用程式,請將每個套件參考更新為 2.1。
  • 移除下列套件的 <DotNetCliToolReference> 元素參考。 這些工具預設會搭載在 .NET Core 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.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.AllMicrosoft.AspNetCore.App 的專案,都應該在專案檔中新增套件的套件參考,即使其包含使用 Microsoft.AspNetCore.AllMicrosoft.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

Main 的變更

下圖顯示對對範本產生的 Program.cs 檔案所做的變更。

old version differences

上圖顯示以紅色標示刪除項目的 2.0 版本。

下圖顯示 2.1 程式碼。 標示綠色的程式碼取代了 2.0 版:

new version differences

下列程式碼顯示 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 來支援新的整合測試基礎結構

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 2.1 會以 Razor 類別庫 (RCL) 的形式提供 ASP.NET CoreIdentity

預設的 2.1 Identity UI 目前不會在 2.0 版本中提供重要的新功能。 將 Identity 取代為 RCL 套件是選用功能。 以 RCL 版本取代範本產生的 Identity 程式碼具有下列優點:

  • 許多檔案移出來源樹狀結構。
  • Identity 的任何錯誤 (bug) 修正程式或新功能都會包含在 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/Logout

其程式碼使用 Identity 並將 2.0 Identity UI 取代為 2.1 Identity 程式庫的應用程式必須考慮到 Identity URL 具有前面加上 URI 的 /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 建構 (Scaffold) 到專案中。 您的專案將使用 ASP.NET CoreIdentityRazor 類別庫。 您可以針對您修改的任何 Identity UI 程式碼產生程式碼和 UI。 將程式碼變更套用至新建構 (Scaffold) 的 UI 程式碼。
  • 刪除現有的 Identity 2.0 程式碼,並使用覆寫所有檔案的選項來將 Identity 建構 (Scaffold) 到專案中。

將 Identity 2.0 UI 取代為 Identity 2.1 Razor 類別庫

本節概述將 ASP.NET Core 2.0 範本產生的 Identity 程式碼取代為 ASP.NET Core IdentityRazor 類別庫的步驟。 下列步驟適用於 Razor Pages 專案,但 MVC 專案的方法很類似。

  • 確認 專案檔已更新為使用 2.1 版本
  • 刪除下列資料夾及其中的所有檔案:
    • 控制器
    • Pages/Account/
    • 擴充
  • 組建專案。
  • 將 Identity 建構 (Scaffold) 到您的專案中:
    • 選取結束 _Layout.cshtml 檔案的專案。
    • 選取資料內容類別右側的 + 圖示。 接受預設名稱。
    • 選取 [新增] 以建立新的資料內容類別別。 需要建立新的資料內容,才能進行建構 (Scaffold)。 您會在下一節中移除新的資料內容。

在建構 (scaffolding) Identity 之後更新

  • 刪除 Areas/Identity/Data/ 資料夾中由 Identity 框架 (scaffolder)產生的 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 Range 標頭

FileResult 預設不會再處理 Accept-Ranges 標頭。 若要啟用 Accept-Ranges 標頭,請將 EnableRangeProcessing 設定為 true

ControllerBase.File 和 PhysicalFile Range 標頭

下列 ControllerBase 方法預設不會再處理 Accept-Ranges 標頭:

若要啟用 Accept-Ranges 標頭,請將 EnableRangeProcessing 參數設定為 true

ASP.NET Core 模組 (ANCM)

如果在安裝 Visual Studio 時,ASP.NET Core 模組 (ANCM) 不是選取的元件,或者如果系統上已安裝舊版的 ANCM,請下載最新的 .NET Core 裝載套件組合安裝程式 (直接下載),並執行安裝程式。 如需詳細資訊,請參閱裝載組合套件

其他變更