從 ASP.NET Core 2.2 移轉至 3.0

作者: Scott AddieRick Anderson

本文說明如何將現有的 ASP.NET Core 2.2 專案更新為 ASP.NET Core 3.0。 建立新的 ASP.NET Core 3.0 專案可能會很有説明:

  • 與 ASP.NET Core 2.2 程式碼比較。
  • 將相關的變更複製到您的 ASP.NET Core 3.0 專案。

必要條件

更新 中的 .NET Core SDK 版本 global.json

如果您的解決方案依賴 global.json 檔案以特定 .NET Core SDK 版本為目標,請將其 version 屬性更新為電腦上安裝的 3.0 版本:

{
  "sdk": {
    "version": "3.0.100"
  }
}

更新專案檔

更新目標 Framework

ASP.NET Core 3.0 和更新版本只會在 .NET Core 上執行。 將 目標 Framework Moniker (TFM) 設定為 netcoreapp3.0

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

移除過時的套件參考

ASP.NET Core 3.0 不會產生大量的 NuGet 套件。 這類套件參考應該從您的專案檔中移除。 針對 ASP.NET Core 2.2 Web 應用程式,請考慮下列專案檔:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

ASP.NET Core 3.0 的更新專案檔:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

更新的 ASP.NET Core 3.0 專案檔:

  • <PropertyGroup> 中:

    • 更新 TFM 至netcoreapp3.0
    • <AspNetCoreHostingModel>移除 專案。 如需詳細資訊,請參閱本檔中 的程式內裝載模型
  • <ItemGroup> 中:

    • Microsoft.AspNetCore.App 已移除。 如需詳細資訊,請參閱本檔中的 Framework 參考
    • Microsoft.AspNetCore.Razor.Design 已移除,且下列套件清單中不再產生。

若要查看不再產生的完整套件清單,請選取下列展開清單:

按一下即可展開不再產生的套件清單
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.All
  • Microsoft.AspNetCore.App
  • Microsoft.AspNetCore.Antiforgery
  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication。 Cookies
  • Microsoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore。 Cookie政策
  • Microsoft.AspNetCore.Cors
  • Microsoft.AspNetCore.Diagnostics
  • Microsoft.AspNetCore.Diagnostics.HealthChecks
  • Microsoft.AspNetCore.HostFiltering
  • Microsoft.AspNetCore.Hosting
  • Microsoft.AspNetCore.Hosting.Abstractions
  • Microsoft.AspNetCore.Hosting.Server.Abstractions
  • Microsoft.AspNetCore.Http
  • Microsoft.AspNetCore.Http.Abstractions
  • Microsoft.AspNetCore.Http.Connections
  • Microsoft.AspNetCore.Http.Extensions
  • Microsoft.AspNetCore.HttpOverrides
  • Microsoft.AspNetCore.HttpsPolicy
  • Microsoft.AspNetCore。Identity
  • Microsoft.AspNetCore.Localization
  • Microsoft.AspNetCore.Localization.Routing
  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.Mvc.Abstractions
  • Microsoft.AspNetCore.Mvc.Analyzers
  • Microsoft.AspNetCore.Mvc.ApiExplorer
  • Microsoft.AspNetCore.Mvc.Api.Analyzers
  • Microsoft.AspNetCore.Mvc.Core
  • Microsoft.AspNetCore.Mvc.Cors
  • Microsoft.AspNetCore.Mvc.DataAnnotations
  • Microsoft.AspNetCore.Mvc.Formatters.Json
  • Microsoft.AspNetCore.Mvc.Formatters.Xml
  • Microsoft.AspNetCore.Mvc.Localization
  • Microsoft.AspNetCore.Mvc。Razor
  • Microsoft.AspNetCore.Mvc. Razor .ViewCompilation
  • Microsoft.AspNetCore.Mvc。 Razor頁面
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.ViewFeatures
  • Microsoft.AspNetCore。Razor
  • Microsoft.AspNetCore. Razor .運行
  • Microsoft.AspNetCore. Razor .設計
  • Microsoft.AspNetCore.ResponseCaching
  • Microsoft.AspNetCore.ResponseCaching.Abstractions
  • Microsoft.AspNetCore.ResponseCompression
  • Microsoft.AspNetCore.Rewrite
  • Microsoft.AspNetCore.Routing
  • Microsoft.AspNetCore.Routing.Abstractions
  • Microsoft.AspNetCore.Server.HttpSys
  • Microsoft.AspNetCore.Server.IIS
  • Microsoft.AspNetCore.Server.IISIntegration
  • Microsoft.AspNetCore.Server。Kestrel
  • Microsoft.AspNetCore.Server. Kestrel .核心
  • Microsoft.AspNetCore.Server. Kestrel .Https
  • Microsoft.AspNetCore.Server. Kestrel .Transport.Abstractions
  • Microsoft.AspNetCore.Server. Kestrel .Transport.Sockets
  • Microsoft.AspNetCore.Session
  • Microsoft.AspNetCore。SignalR
  • Microsoft.AspNetCore. SignalR .核心
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilities
  • Microsoft.Net.Http.Headers

檢閱重大變更

檢閱重大變更

架構參考

可透過上述其中一個套件取得的 ASP.NET Core功能,可做為共用架構的 Microsoft.AspNetCore.App 一部分。 共用架構是一組元件, (.dll檔案) 安裝在機器上,並包含執行時間元件和目標套件。 如需詳細資訊,請參閱共用的架構 \(英文\)。

  • 以 SDK 為目標 Microsoft.NET.Sdk.Web 的專案會隱含參考 Microsoft.AspNetCore.App 架構。

    這些專案不需要其他參考:

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
        ...
    </Project>
    
  • 以 或 SDK 為目標 Microsoft.NET.Sdk 的專案,應該將明確的 FrameworkReference 新增至 Microsoft.AspNetCore.AppMicrosoft.NET.Sdk.Razor

    <Project Sdk="Microsoft.NET.Sdk.Razor">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
      </ItemGroup>
        ...
    </Project>
    

使用 Docker 的架構相依組建

使用相依于 ASP.NET Core共用架構之套件的主控台應用程式架構相依組建,可能會發生下列執行階段錯誤:

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
  - No frameworks were found.

Microsoft.AspNetCore.App是包含 ASP.NET Core執行時間的共用架構,而且只存在於dotnet/core/aspnet Docker 映射上。 3.0 SDK 不會包含共用架構中可用程式庫的重複複本,藉此減少使用 ASP.NET Core 的架構相依組建大小。 這是最多 18 MB 的可能節省成本,但需要 ASP.NET Core執行時間存在/安裝才能執行應用程式。

若要判斷應用程式是否相依性 (ASP.NET Core共用架構上的直接或間接) ,請檢查 runtimeconfig.json 應用程式建置/發佈期間產生的檔案。 下列 JS ON 檔案顯示 ASP.NET Core共用架構的相依性:

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "3.0.0"
    },
    "configProperties": {
      "System.GC.Server": true
    }
  }
}

如果您的應用程式使用 Docker,請使用包含 ASP.NET Core 3.0 的基底映射。 例如: docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0

新增已移除元件的套件參考

ASP.NET Core 3.0 會移除先前是套件參考一部分的 Microsoft.AspNetCore.App 元件。 若要將移除的元件視覺化,請比較兩個共用架構資料夾。 例如,2.2.7 版和 3.0.0 版的比較:

共用架構元件比較

若要繼續使用已移除元件所提供的功能,請參考對應套件的 3.0 版本:

啟動變更

下圖顯示 ASP.NET Core 2.2 Razor Pages Web 應用程式中已刪除和變更的行:

ASP.NET Core 2.2 Razor Web 應用程式中已刪除和變更的行

在上圖中,已刪除的程式碼會以紅色顯示。 已刪除的程式碼不會顯示 cookie 選項程式碼,在比較檔案之前已刪除。

下圖顯示 ASP.NET Core 3.0 Razor Pages Web 應用程式中新增和變更的行:

ASP.NET Core 3.0 Razor Web 應用程式中新增和變更的行

在上圖中,新增的程式碼會以綠色顯示。 如需下列變更的相關資訊:

分析器支援

Microsoft.NET.Sdk.Web 隱含方式參考分析器為目標的專案,先前隨附于 Microsoft.AspNetCore.Mvc.Analyzers 套件。 啟用這些參考不需要其他參考。

如果您的應用程式使用先前使用Microsoft.AspNetCore.Mvc.Api.Analyzers套件隨附的API 分析器,請編輯您的專案檔,以參考隨附于 .NET Core Web SDK 中的分析器:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
    </PropertyGroup>

    ...
</Project>

Razor 類別庫

Razor 提供 MVC UI 元件的類別庫專案必須在專案檔中設定 AddRazorSupportForMvc 屬性:

<PropertyGroup>
  <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>

同處理序裝載模型

專案預設為 ASP.NET Core 3.0 或更新版本中的進程主控模型。 如果專案檔的值是 InProcess ,您可以選擇性地移除 <AspNetCoreHostingModel> 專案檔中的 屬性。

Kestrel

組態

將組態移 Kestrel 轉至 (提供的 ConfigureWebHostDefaultsWeb 主機產生器) Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

如果應用程式以 手動 ConfigureWebHost 方式建立主機, ConfigureWebHostDefaults 而不是 ,請在 Web 主機產生器上呼叫 UseKestrel

public static void Main(string[] args)
{
    var host = new HostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder.UseKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
}

連接中介軟體會取代連接配接器

已從 Kestrel 移除連接配接器 (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) 。 以連接中介軟體取代連接配接器。 連線中介軟體類似于 ASP.NET Core管線中的 HTTP 中介軟體,但適用于較低層級的連線。 HTTPS 和連線記錄:

  • 已從連接配接器移至連接中介軟體。
  • 這些擴充方法的運作方式如同舊版 ASP.NET Core。

如需詳細資訊,請參閱 本文的 ListenOptions.Protocols 一節 Kestrel 中的 TlsFilterConnectionHandler 範例

傳輸抽象概念已移動並設為公用

傳輸 Kestrel 層已公開為 中的 Connections.Abstractions 公用介面。 這些更新的一部分:

  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions 已移除 和 相關聯的型別。
  • NoDelay 已從 ListenOptions 移至傳輸選項。
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode 已從 KestrelServerOptions 中移除。

如需詳細資訊,請參閱下列 GitHub 資源:

Kestrel 要求預告片標頭

針對以舊版 ASP.NET Core為目標的應用程式:

  • Kestrel 將 HTTP/1.1 區塊化預告片標頭新增至要求標頭集合。
  • 在要求本文讀取到結尾之後,即可使用預告片。

這會導致標頭和預告片之間的模棱兩可,因此預告片已移至 3.0 中的新集合 (RequestTrailerExtensions) 。

HTTP/2 要求預告片如下:

  • ASP.NET Core 2.2 中無法使用。
  • 3.0 提供作為 RequestTrailerExtensions

新的要求擴充方法會存在以存取這些預告片。 如同 HTTP/1.1,在要求本文讀取到結尾之後,可以使用預告片。

針對 3.0 版,有下列 RequestTrailerExtensions 方法可供使用:

  • GetDeclaredTrailers:取得要求 Trailer 標頭,其中列出主體之後預期哪些預告片。
  • SupportsTrailers:指出要求是否支援接收預告片標頭。
  • CheckTrailersAvailable:檢查要求是否支援預告片,以及是否可供讀取。 此檢查不會假設有預告片可供讀取。 即使 true 此方法傳回,也不會有預告片可讀取。
  • GetTrailer:從回應取得要求的尾端標頭。 呼叫 GetTrailer 之前檢查 SupportsTrailers ,如果 NotSupportedException 要求不支援尾端標頭,則可能會發生 。

如需詳細資訊,請參閱 將要求預告片放在個別集合中, (dotnet/AspNetCore #10410)

AllowSynchronousIO 已停用

AllowSynchronousIO 啟用或停用同步 I/O API,例如 HttpRequest.Body.ReadHttpResponse.Body.WriteStream.Flush 。 這些 API 是執行緒耗盡的來源,導致應用程式當機。 在 3.0 中, AllowSynchronousIO 預設為停用。 如需詳細資訊,請參閱 文章中的同步 I/O 一 Kestrel 節

如果需要同步 I/O,則可以藉由 AllowSynchronousIO 在呼叫 ConfigureKestrel 時 (伺服器上設定選項來啟用,例如, Kestrel 如果使用) 。 請注意,伺服器 (Kestrel 、HttpSys、TestServer 等) 全都有不會影響其他伺服器的選項 AllowSynchronousIO 。 您可以使用 選項,針對每個要求 IHttpBodyControlFeature.AllowSynchronousIO 的所有伺服器啟用同步 I/O:

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();

if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

如果您在Dispose中呼叫同步 API 的實作或其他資料流程時遇到問題 TextWriter ,請改為呼叫新的 DisposeAsync API。

如需詳細資訊,請參閱 在所有伺服器中停用 AllowSynchronousIO (dotnet/AspNetCore #7644)

輸出格式器緩衝處理

Newtonsoft.JsonXmlSerializerDataContractSerializer 型輸出格式器僅支援同步序列化。 若要允許這些格式器使用伺服器的 AllowSynchronousIO 限制,MVC 會先緩衝處理這些格式子的輸出,再寫入磁片。 由於緩衝處理,MVC 會在使用這些格式器回應時包含 Content-Length 標頭。

System.Text.Json 支援非同步序列化, System.Text.Json 因此基式格式器不會緩衝處理。 請考慮使用此格式器來改善效能。

若要停用緩衝處理,應用程式可以在 SuppressOutputFormatterBuffering 啟動時進行設定:

services.AddControllers(options => options.SuppressOutputFormatterBuffering = true)

請注意,如果未 AllowSynchronousIO 設定,這可能會導致應用程式擲回執行時間例外狀況。

Microsoft.AspNetCore.Server. Kestrel .已移除 Https 元件

在 ASP.NET Core 2.1 中,Microsoft.AspNetCore.Server Kestrel 的內容。Https.dll已移至Microsoft.AspNetCore.Server。 Kestrel 。Core.dll。 這是使用 TypeForwardedTo 屬性的非中斷性更新。 針對 3.0,空 的 Microsoft.AspNetCore.Server。 Kestrel 。已移除元件 和 NuGet 套件Https.dll。

參考Microsoft.AspNetCore.Server.的連結 Kestrel 庫。Https應該將 ASP.NET Core相依性更新為 2.1 或更新版本。

以 ASP.NET Core 2.1 或更新版本為目標的應用程式和程式庫應該移除Microsoft.AspNetCore.Server Kestrel 的任何直接參考。Https套件。

Newtonsoft.Json (Json.NET) 支援

改善 ASP.NET Core共用架構的工作中,Newtonsoft.Json (Json.NET) 已從 ASP.NET Core共用架構中移除。

ASP.NET Core的預設 JS ON 序列化程式現在是 System.Text.Json ,這是 .NET Core 3.0 的新功能。 請考慮盡可能使用 System.Text.Json 。 它是高效能的,而且不需要額外的程式庫相依性。 不過,由於 System.Text.Json 是新的,所以目前可能缺少您的應用程式所需的功能。 如需詳細資訊,請參閱 如何從 Newtonsoft.Json 移轉至 System.Text.Json

在 ASP.NET Core 3.0 SignalR 專案中使用 Newtonsoft.Json

  • 安裝 Microsoft.AspNetCore. SignalR 。Protocols.NewtonsoftJson NuGet 套件。

  • 在用戶端上,將方法呼叫鏈結 AddNewtonsoftJsonProtocolHubConnectionBuilder 實例:

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • 在伺服器上,將方法呼叫鏈結 AddNewtonsoftJsonProtocolAddSignalR 中的 Startup.ConfigureServices 方法呼叫:

    services.AddSignalR()
        .AddNewtonsoftJsonProtocol(...);
    

在 ASP.NET Core 3.0 MVC 專案中使用 Newtonsoft.Json

  • 安裝 Microsoft.AspNetCore.Mvc.NewtonsoftJson 套件。

  • 更新 Startup.ConfigureServices 以呼叫 AddNewtonsoftJson

    services.AddMvc()
        .AddNewtonsoftJson();
    

    AddNewtonsoftJson 與新的 MVC 服務註冊方法相容:

    • AddRazorPages
    • AddControllersWithViews
    • AddControllers
    services.AddControllers()
        .AddNewtonsoftJson();
    

    Newtonsoft.Json 設定可以在 呼叫 AddNewtonsoftJson 中設定:

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

    注意:AddNewtonsoftJson如果方法無法使用,請確定您已安裝 Microsoft.AspNetCore.Mvc.NewtonsoftJson 套件。 常見的錯誤是安裝 Newtonsoft.Json 套件,而不是 Microsoft.AspNetCore.Mvc.NewtonsoftJson 套件。

如需詳細資訊,請參閱 新增 Newtonsoft.Json 型 JS ON 格式支援

MVC 服務註冊

ASP.NET Core 3.0 新增了在 內 Startup.ConfigureServices 註冊 MVC 案例的新選項。

有三個與 MVC 案例 IServiceCollection 相關的新最上層擴充方法可供使用。 範本會使用這些新方法,而不是 AddMvc 。 不過, AddMvc 在舊版中仍會繼續運作。

下列範例新增了控制器和 API 相關功能的支援,但不支援檢視或頁面。 API 範本會使用此程式碼:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

下列範例會新增控制器、API 相關功能和檢視的支援,但不支援頁面。 Web 應用程式 (MVC) 範本會使用此程式碼:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
}

下列範例會新增 Razor Pages 的支援和最小控制器支援。 Web 應用程式範本會使用此程式碼:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
}

也可以結合新的方法。 下列範例相當於在 ASP.NET Core 2.2 中呼叫 AddMvc

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
}

路由啟動程式碼

如果應用程式呼叫 UseMvcUseSignalR ,請盡可能將應用程式遷移至 端點路由 。 為了改善與舊版 MVC 的端點路由相容性,我們已還原 ASP.NET Core 2.2 中引進的 URL 產生部分變更。 如果您在 2.2 中使用端點路由時遇到問題,預期 ASP.NET Core 3.0 的改善,但有下列例外狀況:

  • 如果應用程式實作 IRouter 或繼承自 Route ,請使用 DynamicRouteValuesTransformer 做為取代專案。
  • 如果應用程式直接存取 MVC 內的 URL 來剖 RouteData.Routers 析 URL,您可以使用 LinkParser.ParsePathByEndpointName來取代此專案。
    • 使用路由名稱定義路由。
    • 使用 LinkParser.ParsePathByEndpointName 並傳入所需的路由名稱。

端點路由支援與 相同的路由模式語法和路由模式撰寫功能 IRouter 。 端點路由支援 IRouteConstraint 。 端點路由支援 [Route][HttpGet] 和其他 MVC 路由屬性。

對於大部分的應用程式,只需要 Startup 變更。

移轉 Startup.Configure

一般建議:

  • 加入 UseRouting

  • 如果應用程式呼叫 UseStaticFiles ,請先放置 UseStaticFilesUseRouting

  • 如果應用程式使用 或 [Authorize] 之類的 AuthorizePage 驗證/授權功能,請呼叫 UseAuthenticationUseAuthorizationafterUseCorsUseRouting 但在 之前 UseEndpoints

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • 將 或 UseSignalR 取代 UseMvcUseEndpoints

  • 如果應用程式使用CORS案例,例如 [EnableCors] ,請在任何其他使用 CORS (的中介軟體之前呼叫 UseCors ,例如,在 、 UseAuthorizationUseEndpoints) 之前 UseAuthentication 放置 UseCors

  • 將 取代 IHostingEnvironmentIWebHostEnvironment ,並新增 using 命名空間的 Microsoft.AspNetCore.Hosting 語句。

  • 將 取代 IApplicationLifetimeIHostApplicationLifetime 命名空間 Microsoft.Extensions.Hosting) (。

  • 將 取代 EnvironmentNameEnvironments 命名空間 Microsoft.Extensions.Hosting) (。

下列程式碼是一般 ASP.NET Core 2.2 應用程式中的 Startup.Configure 範例:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseSignalR(hubs =>
    {
        hubs.MapHub<ChatHub>("/chat");
    });

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

更新先前 Startup.Configure 的程式碼之後:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chat");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

警告

對於大部分的應用程式,對 、 和 的呼叫 UseAuthentication 必須出現在 對 和 UseEndpoints 的呼叫 UseRouting 之間,才能 UseCors 生效。 UseAuthorization

健康情況檢查

健康情況檢查會搭配泛型主機使用端點路由。 在 中 Startup.Configure ,使用端點 URL 或相對路徑在端點產生器上呼叫 MapHealthChecks

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

健康情況檢查端點可以:

  • 指定一或多個允許的主機/埠。
  • 需要授權。
  • 需要 CORS。

如需詳細資訊,請參閱 ASP.NET Core 中的健康狀態檢查

安全性中介軟體指引

授權和 CORS 的支援會與 中介軟體 方法整合。 這可讓您在這些案例中使用相同的中介軟體和功能。 此版本中會提供更新的授權中介軟體,並增強 CORS 中介軟體,以便了解 MVC 控制器所使用的屬性。

CORS

先前,CORS 可能很難設定。 中介軟體已提供供某些使用案例使用,但 MVC 篩選器旨在在其他使用案例中 不使用 中介軟體。 使用 ASP.NET Core 3.0 時,建議所有需要 CORS 的應用程式搭配端點路由使用 CORS 中介軟體。 UseCors 可以使用預設原則來提供,而且 [EnableCors] 屬性 [DisableCors] 可用來視需要覆寫預設原則。

在下例中︰

  • 所有具有具名原則的 default 端點都會啟用 CORS。
  • 類別 MyController 會停用具有 屬性的 [DisableCors] CORS。
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseCors("default");

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[DisableCors]
public class MyController : ControllerBase
{
    ...
}

授權

在舊版 ASP.NET Core中,授權支援是透過 [Authorize] 屬性提供。 授權中介軟體無法使用。 在 ASP.NET Core 3.0 中,需要授權中介軟體。 建議您將 ASP.NET Core授權中介軟體 (UseAuthorization) 緊接在 之後 UseAuthentication 。 授權中介軟體也可以設定為預設原則,以覆寫此原則。

在 ASP.NET Core 3.0 或更新版本中, UseAuthorization 會在 中 Startup.Configure 呼叫 ,而且下列 HomeController 專案需要已登入的使用者:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

public class HomeController : Controller
{
    [Authorize]
    public IActionResult BuyWidgets()
    {
        ...
    }
}

使用端點路由時,建議您不要設定 AuthorizeFilter 並改為依賴授權中介軟體。 如果應用程式在 MVC 中使用 AuthorizeFilter 做為全域篩選準則,建議您重構程式碼,以在呼叫 AddAuthorization 中提供原則。

DefaultPolicy 開始會設定為需要驗證,因此不需要額外的設定。 在下列範例中,MVC 端點會標示為 RequireAuthorization ,因此所有要求都必須根據 DefaultPolicy 授權。 不過, HomeController 允許在沒有使用者登入應用程式的情況下存取,因為 [AllowAnonymous]

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

特定端點的授權

您也可以針對特定端點類別設定授權。 下列程式碼是將設定全域 AuthorizeFilter 的 MVC 應用程式轉換為需要授權之特定原則的應用程式的範例:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    static readonly string _RequireAuthenticatedUserPolicy = 
                            "RequireAuthenticatedUserPolicy";
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        // Pre 3.0:
        // services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(...));

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
                        builder => builder.RequireAuthenticatedUser()));

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute()
                .RequireAuthorization(_RequireAuthenticatedUserPolicy);
            endpoints.MapRazorPages();
        });
    }
}

您也可以自訂原則。 設定 DefaultPolicy 為需要驗證:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .Build();
        });

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute().RequireAuthorization();
            endpoints.MapRazorPages();
        });
    }
}
[AllowAnonymous]
public class HomeController : Controller
{

或者,所有端點都可以設定為不需要授權,或 RequireAuthorization 藉由設定 FallbackPolicy 來要求 [Authorize] 授權。 FallbackPolicy與 不同 DefaultPolicyDefaultPolicy會由 [Authorize]RequireAuthorization 觸發,而 FallbackPolicy 當未設定其他原則時,就會觸發 。 FallbackPolicy 一開始會設定為允許沒有授權的要求。

下列範例與上述 DefaultPolicy 範例相同,但會使用 FallbackPolicy 在指定 時 [AllowAnonymous] 以外的所有端點上一律要求驗證:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

中介軟體的授權可在沒有任何特定授權知識的架構的情況下運作。 例如, 健康情況檢查 沒有特定的授權知識,但健康情況檢查可以有中介軟體所套用的可設定授權原則。

此外,每個端點都可以自訂其授權需求。 在下列範例中, UseAuthorization 會處理 的 DefaultPolicy 授權,但 /healthz 健康情況檢查端點需要 admin 使用者:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapHealthChecks("/healthz")
            .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
    });
}

某些案例會實作保護。 端點中介軟體會在因為遺漏中介軟體而略過授權或 CORS 原則時擲回例外狀況。 分析器支援,提供有關設定錯誤的其他意見反應正在進行中。

自訂授權處理常式

如果應用程式使用自訂 授權處理常式,端點路由會將不同的資源類型傳遞給 MVC 以外的處理常式。 預期授權處理常式內容資源的處理常式類型 AuthorizationFilterContext (MVC 篩選準則所提供的 資源類型) 將需要更新,才能處理 RouteEndpoint 類型 (端點路由) 授與授權處理常式的資源類型。

MVC 仍會使用 AuthorizationFilterContext 資源,因此,如果應用程式使用 MVC 授權篩選器以及端點路由授權,可能需要處理這兩種類型的資源。

SignalR

中樞的 SignalR 對應現在會在 內 UseEndpoints 進行。

使用 對應每個中 MapHub 樞。 如同舊版,每個中樞都會明確列出。

在下列範例中,會新增中 ChatHubSignalR 樞的支援:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>();
    });
}

有新的選項可控制來自用戶端的訊息大小限制。 例如,在 Startup.ConfigureServices 中:

services.AddSignalR(hubOptions =>
{
    hubOptions.MaximumReceiveMessageSize = 32768;
});

在 ASP.NET Core 2.2 中,您可以設定 TransportMaxBufferSize ,並有效地控制訊息大小上限。 在 ASP.NET Core 3.0 中,該選項現在只會控制在觀察到反壓之前的大小上限。

SignalR 共用架構中的元件

SignalRASP.NET Core伺服器端元件現在會與 .NET Core SDK 一起安裝。 如需詳細資訊,請參閱本檔中 的移除過時的套件參考

MVC 控制器

控制器的對應現在會在 內 UseEndpoints 進行。

如果應用程式使用屬性路由,請新增 MapControllers 。 由於路由包含 ASP.NET Core 3.0 或更新版本中許多架構的支援,因此新增屬性路由控制器是加入宣告。

取代下列項目:

  • MapControllerRouteMapRoute
  • MapAreaControllerRouteMapAreaRoute

由於路由現在包含 MVC 以外的支援,因此術語已變更,讓這些方法清楚說明其用途。 之類的 MapControllerRoute//MapAreaControllerRouteMapDefaultControllerRoute 傳統路由會依新增的順序套用。 先放置更明確的路由 (,例如區域) 的路由。

在下例中︰

  • MapControllers 新增對屬性路由控制器的支援。
  • MapAreaControllerRoute 為區域中的控制器新增傳統路由。
  • MapControllerRoute 新增控制器的傳統路由。
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapAreaControllerRoute(
            "admin",
            "admin",
            "Admin/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllerRoute(
            "default", "{controller=Home}/{action=Index}/{id?}");
    });
}

從控制器動作名稱移除非同步尾碼

在 ASP.NET Core 3.0 中,ASP.NET Core MVC 會從控制器動作名稱中移除 Async 尾碼。 路由和連結產生都會受到這個新預設值的影響。 例如:

public class ProductsController : Controller
{
    public async Task<IActionResult> ListAsync()
    {
        var model = await _dbContext.Products.ToListAsync();
        return View(model);
    }
}

ASP.NET Core 3.0 之前:

  • 上述動作可以在 Products/ListAsync 路由存取。

  • 需要產生連結, Async 才能指定尾碼。 例如:

    <a asp-controller="Products" asp-action="ListAsync">List</a>
    

在 ASP.NET Core 3.0 中:

  • 上述動作可以在 Products/List 路由存取。

  • 連結產生不需要指定 Async 尾碼。 例如:

    <a asp-controller="Products" asp-action="List">List</a>
    

這項變更不會影響使用 [ActionName] 屬性指定的名稱。 使用 中的 Startup.ConfigureServices 下列程式碼可以停用預設行為:

services.AddMvc(options =>
    options.SuppressAsyncSuffixInActionNames = false);

使用 Url.Link 和類似 API 的連結產生 (有一些差異,例如) 。 其中包括:

  • 根據預設,使用端點路由時,不一定會保留所產生 URI 中的路由參數大小寫。 此行為可以使用 介面來控制 IOutboundParameterTransformer
  • 在不存在的控制器/動作或頁面 (產生無效路由的 URI,) 會產生端點路由下的空字串,而不是產生不正確 URI。
  • 環境值 (來自目前內容) 路由參數不會自動用於與端點路由的連結產生。 先前,當產生另一個動作的連結 (或頁面) 時, 會從目前的 路由環境值推斷未指定的路由值。 使用端點路由時,必須在連結產生期間明確指定所有路由參數。

Razor Pages

對應 Razor 頁面現在會在 內 UseEndpoints 發生。

如果應用程式使用 Razor Pages,請新增 MapRazorPages 。 由於端點路由包含許多架構的支援,因此新增 Razor 頁面現在已加入宣告。

在下列 Startup.Configure 方法中, MapRazorPages 新增 Pages 的支援 Razor :

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

不使用端點路由使用 MVC

透過 UseMvcUseMvcWithDefaultRoute 在 ASP.NET Core 3.0 中使用 MVC 需要在 內 Startup.ConfigureServices 明確加入宣告。 這是必要的,因為 MVC 必須知道它是否可以在初始化期間依賴授權和 CORS 中介軟體。 提供分析器,如果應用程式嘗試使用不支援的組態,就會發出警告。

如果應用程式需要舊版 IRouter 支援,請在 中使用下列任何方法 Startup.ConfigureServices 停用 EnableEndpointRouting

services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);

健康狀態檢查

健康情況檢查可作為具有端點路由的 路由器軟體

新增 MapHealthChecks 以搭配端點路由使用健康情況檢查。 方法 MapHealthChecks 接受類似 的 UseHealthChecks 引數。 使用 MapHealthChecks over UseHealthChecks 的優點是能夠套用授權,並更精細地控制比對原則。

在下列範例中, MapHealthChecks 針對 位於 /healthz 的健康情況檢查端點呼叫 :

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
    });
}

HostBuilder 取代 WebHostBuilder

ASP.NET Core 3.0 範本使用一般主機。 舊版使用 Web 主機。 下列程式碼顯示 ASP.NET Core 3.0 範本產生的 Program 類別:

// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

下列程式碼顯示 ASP.NET Core 2.2 範本產生的 Program 類別:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

IWebHostBuilder 會保留在 3.0 中,而且是上述程式碼範例中所見的類型 webBuilderWebHostBuilder 將在未來的版本中淘汰,並以 取代 HostBuilder

從 到 的最重大變更 WebHostBuilderHostBuilder 是相 依性插入 (DI) 。 使用 HostBuilder 時,您只能將下列內容插入 Startup 的建構函式中:

HostBuilderDI 條件約束:

  • 讓 DI 容器只能建置一次。
  • 避免產生的物件存留期問題,例如解決多個單一實例。

如需詳細資訊,請參閱避免在 ASP.NET Core 3 中插入啟動服務

AddAuthorization 已移至不同的元件

Microsoft.AspNetCore.Authorization.dll中的 ASP.NET Core 2.2 和更低 AddAuthorization 方法:

  • 已重新命名 AddAuthorizationCore
  • 已移至 Microsoft.AspNetCore.Authorization.Policy.dll

使用 Microsoft.AspNetCore.Authorization.dllMicrosoft.AspNetCore.Authorization.Policy.dll 的應用程式不會受到影響。

未使用 Microsoft.AspNetCore.Authorization.Policy.dll 的應用程式應該執行下列其中一項:

  • 將參考新增至 Microsoft.AspNetCore.Authorization.Policy.dll。 此方法適用于大部分的應用程式,而且都是必要專案。
  • 切換至使用 AddAuthorizationCore

如需詳細資訊,請參閱 ) 多載的重大 AddAuthorization(o => 變更存在於不同的元件中 #386

Identity UI

IdentityASP.NET Core 3.0 的 UI 更新:

  • 將套件參考新增至 Microsoft.AspNetCore. Identity 。UI
  • 不使用 Razor Pages 的應用程式必須呼叫 MapRazorPages 。 請參閱Razor本檔中的頁面。
  • Bootstrap 4 是預設 UI 架構。 IdentityUIFrameworkVersion設定專案屬性以變更預設值。 如需詳細資訊,請參閱 此 GitHub 公告

SignalR

SignalRJavaScript 用戶端已從 @aspnet/signalr 變更為 @microsoft/signalr 。 若要回應這項變更,請變更檔案、 require 語句和 ECMAScript import 語句中的 package.json 參考。

System.Text.Json 是預設通訊協定

System.Text.Json 現在是用戶端和伺服器所使用的預設中樞通訊協定。

在 中 Startup.ConfigureServices ,呼叫 AddJsonProtocol 以設定序列化程式選項。

伺服器:

services.AddSignalR(...)
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        })

用戶端:

new HubConnectionBuilder()
    .WithUrl("/chathub")
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.WriteIndented = false;
    })
    .Build();

切換至 Newtonsoft.Json

如果您使用 System.Text.Json 不支援的 Newtonsoft.Json 功能,您可以切換回 Newtonsoft.Json 。 請參閱本文稍早的ASP.NET Core 3.0 SignalR 專案中使用 Newtonsoft.Json

Redis 分散式快取

Microsoft.Extensions.Caching.Redis套件不適用於 ASP.NET Core 3.0 或更新版本應用程式。 將套件參考取代為 Microsoft.Extensions.Caching.StackExchangeRedis。 如需詳細資訊,請參閱ASP.NET Core 中的分散式快取

加入宣告執行時間編譯

在 ASP.NET Core 3.0 之前,檢視的執行時間編譯是架構的隱含功能。 執行時間編譯可補充檢視的建置時間編譯。 它可讓架構 Razor 在修改檔案時編譯檢視和頁面 (.cshtml 檔案) ,而不需要重建整個應用程式。 此功能支援在 IDE 中快速編輯及重新整理瀏覽器以檢視變更的案例。

在 ASP.NET Core 3.0 中,執行時間編譯是加入宣告案例。 建置時間編譯是預設啟用之檢視編譯的唯一機制。 執行時間依賴 visual Studio 或dotnet-watch在 Visual Studio Code,以在偵測到檔案變更 .cshtml 時重建專案。 在 Visual Studio 中,變更為 .cs.cshtml.razor 專案中執行的檔案, (Ctrl+F5) ,但未 (F5) 偵錯,觸發專案的重新編譯。

若要在 ASP.NET Core 3.0 專案中啟用執行時間編譯:

  1. 安裝 Microsoft.AspNetCore.Mvc. Razor 。RuntimeCompilation NuGet 套件。

  2. 更新 Startup.ConfigureServices 以呼叫 AddRazorRuntimeCompilation

    針對 ASP.NET Core MVC,請使用下列程式碼:

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    針對 ASP.NET Core Razor Pages,請使用下列程式碼:

    services.AddRazorPages()
        .AddRazorRuntimeCompilation(...);
    

https://github.com/aspnet/samples/tree/main/samples/aspnetcore/mvc/runtimecompilation 範例示範在開發環境中有條件地啟用執行時間編譯的範例。

如需檔案編譯的詳細資訊 Razor ,請參閱Razor ASP.NET Core 中的檔案編譯

透過多重目標移轉程式庫

程式庫通常需要支援多個版本的 ASP.NET Core。 針對舊版 ASP.NET Core編譯的大部分程式庫都應該繼續運作,而不會發生問題。 下列條件需要跨編譯應用程式:

  • 程式庫依賴具有二進位 中斷性變更的功能。
  • 此程式庫想要利用 ASP.NET Core 3.0 中的新功能。

例如:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
  </ItemGroup>
</Project>

使用 #ifdefs 來啟用 ASP.NET Core 3.0 特定的 API:

var webRootFileProvider =
#if NETCOREAPP3_0
    GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
    GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif

如需在類別庫中使用 ASP.NET Core API 的詳細資訊,請參閱在類別庫中使用 ASP.NET Core API

其他變更

.NET Core 3.0 和更新版本中的驗證系統會將不可為 Null 的參數或系結屬性視為具有 [Required] 屬性。 如需詳細資訊,請參閱 [必要] 屬性

發佈

刪除專案目錄中的 binobj 資料夾。

TestServer

對於直接與一般主機搭配使用 TestServer 的應用程式,請在 中 ConfigureWebHost 建立 TestServer 上的 IWebHostBuilder

[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .Configure(app => { });
        })
    .StartAsync();

    var response = await host.GetTestServer().CreateClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

重大 API 變更

檢閱重大變更:

使用 catch-all 參數的端點路由

警告

catch-all參數可能會因為路由中的錯誤而不正確地比對路由。 受這個 Bug 影響的應用程式具有下列特性:

  • 全擷取路由,例如 {**slug}"
  • catch-all 路由無法比對它應該相符的要求。
  • 移除其他路由會使 catch-all 路由開始運作。

如需遇到此錯誤的範例,請參閱 GitHub Bugs 1867716579

此錯誤的加入宣告修正包含在 .NET Core 3.1.301 SDK 和更新版本中。 下列程式碼會設定修正此 Bug 的內部參數:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Azure App 服務上的 .NET Core 3.0

.NET Core 的推出已完成Azure App 服務。 .NET Core 3.0 適用于所有Azure App 服務資料中心。

ASP.NET Core模組 (ANCM)

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