從 ASP.NET Core 2.2 移轉到 3.0
作者:Scott Addie 與 Rick 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 專案。
必要條件
- Visual Studio 2019 和 ASP.NET 與 Web 開發工作負載
- .NET Core 3.0 SDK
更新 global.json 中的 .NET Core SDK 版本
如果您的解決方案依賴 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>
元素。 如需詳細資訊,請參閱本文件中的內含式裝載模型。
- 將 TFM 更新至
在
<ItemGroup>
:Microsoft.AspNetCore.App
會遭到移除。 如需詳細資訊,請參閱本文件中的架構參考。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.CookiePolicy
- 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.RazorPages
- Microsoft.AspNetCore.Mvc.TagHelpers
- Microsoft.AspNetCore.Mvc.ViewFeatures
- Microsoft.AspNetCore.Razor
- Microsoft.AspNetCore.Razor.Runtime
- Microsoft.AspNetCore.Razor.Design
- 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.Core
- 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.Core
- Microsoft.AspNetCore.StaticFiles
- Microsoft.AspNetCore.WebSockets
- Microsoft.AspNetCore.WebUtilities
- Microsoft.Net.Http.Headers
檢閱中斷性變更
架構參考
透過上述其中一個套件提供的 ASP.NET Core 功能,可作為 Microsoft.AspNetCore.App
共用架構的一部分。 共用架構是一組安裝在電腦上的組建 (.dll 檔案),並包含執行階段元件和目標套件。 如需詳細資訊,請參閱共用的架構 \(英文\)。
以
Microsoft.NET.Sdk.Web
SDK 為目標的專案會隱含地參考Microsoft.AspNetCore.App
架構。這些專案不需要其他參考:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> ... </Project>
以
Microsoft.NET.Sdk
或Microsoft.NET.Sdk.Razor
SDK 為目標的專案,應該將明確FrameworkReference
新增至Microsoft.AspNetCore.App
:<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
檔案。 下列 JSON 檔案顯示與 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 版本:
具有個別使用者帳戶的範本產生 Web 應用程式需要新增下列套件:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> <UserSecretsId>My-secret</UserSecretsId> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0" /> </ItemGroup> </Project>
-
如需參考資料庫提供者特定套件的詳細資訊,請參閱資料庫提供者。
Identity UI
針對 Identity UI 的支援可藉由參考 Microsoft.AspNetCore.Identity.UI 套件來新增。
SPA 服務
驗證:支援第三方驗證流程是以 NuGet 套件的形式提供:
- Facebook OAuth (Microsoft.AspNetCore.Authentication.Facebook)
- Google OAuth (Microsoft.AspNetCore.Authentication.Google)
- Microsoft 帳戶驗證 (Microsoft.AspNetCore.Authentication.MicrosoftAccount)
- OpenID Connect 驗證 (Microsoft.AspNetCore.Authentication.OpenIdConnect)
- OpenID Connect 持有人權杖 (Microsoft.AspNetCore.Authentication.JwtBearer)
- Twitter OAuth (Microsoft.AspNetCore.Authentication.Twitter)
- WsFederation 驗證 (Microsoft.AspNetCore.Authentication.WsFederation)
針對
System.Net.HttpClient
的格式化和內容交涉支援:Microsoft.AspNet.WebApi.Client NuGet 套件使用例如ReadAsAsync
和PostJsonAsync
的 API 提供對System.Net.HttpClient
的有用擴充性。 不過,此套件相依於Newtonsoft.Json
,而非System.Text.Json
。 舉例來說,這表示會略過由JsonPropertyNameAttribute
(System.Text.Json
) 指定的序列化屬性名稱。 有一個較新的 NuGet 套件包含類似的擴充方法,但是使用System.Text.Json
:System.Net.Http.Json。Razor 執行階段編譯:支援 Razor 檢視和頁面的執行階段編譯,現在屬於 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation。
MVC
Newtonsoft.Json
(Json.NET) 支援:支援透過Newtonsoft.Json
使用 MVC 現在屬於Microsoft.AspNetCore.Mvc.NewtonsoftJson
。
啟動變更
下圖顯示 ASP.NET Core 2.2 Razor Pages Web 應用程式中已刪除和已變更的行:
在上圖中,已刪除的程式碼會以紅色顯示。 已刪除的程式碼不會顯示 cookie 選項程式碼,在比較檔案之前已刪除。
下圖顯示 ASP.NET Core 3.0 Razor Pages Web 應用程式中已新增和已變更的行:
在上圖中,新增的程式碼會以綠色顯示。 如需下列變更的詳細資訊:
services.AddMvc
至services.AddRazorPages
,請參閱本文件中的 MVC 服務註冊。CompatibilityVersion
,請參閱 ASP.NET Core MVC 的相容性版本。IHostingEnvironment
至IWebHostEnvironment
,請參閱本 GitHub 公告。app.UseAuthorization
已新增至範本,顯示必須新增訂單授權中介軟體。 如果應用程式未使用授權,您可以安全地移除對app.UseAuthorization
的呼叫。app.UseEndpoints
,請參閱本文件中的 Razor Pages 或移轉 Startup.Configure。
分析器支援
以 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 類別庫
為 MVC 提供 UI 元件的 Razor 類別庫專案,必須在專案檔中設定 AddRazorSupportForMvc
屬性:
<PropertyGroup>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>
同處理序主控模型
專案在 ASP.NET Core 3.0 或更新版本中預設為內含式裝載模型。 如果專案檔中 <AspNetCoreHostingModel>
屬性的值為 InProcess
,您可以選擇性地將其移除。
Kestrel
組態
將 Kestrel 組態移轉至由 ConfigureWebHostDefaults
(Program.cs
) 提供的 Web 主機建立器:
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();
}
連線中介軟體會取代連線配接器
連線配接器 (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter
) 已從 Kestrel 中移除。 以連線中介軟體取代連線配接器。 連線中介軟體類似於 ASP.NET Core 管線中的 HTTP 中介軟體,但是適用於較低層級的連線。 HTTPS 和連線記錄:
- 已從連線配接器移至連線中介軟體。
- 這些擴充方法可在舊版 ASP.NET Core 中運作。
如需詳細資訊,請參閱 Kestrel 文章中 ListenOptions.Protocols 一節中的 TlsFilterConnectionHandler 範例。
已移動並公開傳輸抽象概念
Kestrel 傳輸層已公開為 Connections.Abstractions
中的公用介面。 作為這些更新的一部分:
- 已移除
Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions
和相關聯型別。 - NoDelay 已從 ListenOptions 移至傳輸選項。
Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode
已從 KestrelServerOptions 移除。
如需詳細資訊,請參閱下列 GitHub 資源:
- 用戶端/伺服器網路抽象概念 (dotnet/AspNetCore #10308)
- 實作新的基岩接聽程式抽象概念並且將 Kestrel 重新設定平台在頂端 (dotnet/AspNetCore #10321)
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.Read
、HttpResponse.Body.Write
和 Stream.Flush
。 這些 API 是導致應用程式當機的執行緒耗盡來源。 在 3.0 中,預設會停用 AllowSynchronousIO
。 如需詳細資訊,請參閱 Kestrel文章中的同步 I/O 一節。
如果需要同步 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.Json、XmlSerializer 和 DataContractSerializer 型輸出格式器僅支援同步序列化。 為了允許這些格式器使用伺服器的 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.Https.dll 組件和 NuGet 套件已移除。
參考 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 的預設 JSON 序列化程式現在是 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 套件。
在用戶端上,將
AddNewtonsoftJsonProtocol
方法呼叫鏈結到HubConnectionBuilder
執行個體:new HubConnectionBuilder() .WithUrl("/chathub") .AddNewtonsoftJsonProtocol(...) .Build();
在伺服器上,將
AddNewtonsoftJsonProtocol
方法呼叫鏈結到Startup.ConfigureServices
中的AddSignalR
方法呼叫:services.AddSignalR() .AddNewtonsoftJsonProtocol(...);
在 ASP.NET Core 3.0 MVC 專案中使用 Newtonsoft.Json
更新
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 型 JSON 格式支援。
MVC 服務註冊
ASP.NET Core 3.0 會新增選項,以在 Startup.ConfigureServices
內註冊 MVC 案例。
有三個與 IServiceCollection
上 MVC 案例相關的新最上層擴充方法可供使用。 範本會使用這些新方法,而不是 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();
}
路由啟動程式碼
如果應用程式呼叫 UseMvc
或 UseSignalR
,請盡可能將應用程式移轉至端點路由。 為了改善與舊版 MVC 的端點路由相容性,我們已還原 ASP.NET Core 2.2 中所引進 URL 產生的一些變更。 如果您在 2.2 中使用端點路由時遇到問題,預期在 ASP.NET Core 3.0 中可改善,但是有以下例外狀況:
- 如果應用程式實作
IRouter
或繼承自Route
,請使用 DynamicRouteValuesTransformer 作為取代項目。 - 如果應用程式直接存取 MVC 內的
RouteData.Routers
來剖析 URL,您可以使用 LinkParser.ParsePathByEndpointName 加以取代。- 使用路由名稱定義路由。
- 使用
LinkParser.ParsePathByEndpointName
並傳入所需的路由名稱。
端點路由支援與 IRouter
相同的路由模式語法和路由模式撰寫功能。 端點路由支援 IRouteConstraint
。 端點路由支援 [Route]
、[HttpGet]
和其他 MVC 路由屬性。
對於大部分的應用程式,只有 Startup
需要變更。
移轉 Startup.Configure
一般建議:
加入
UseRouting
。如果應用程式呼叫
UseStaticFiles
,請在UseRouting
前面放置UseStaticFiles
。如果應用程式使用例如
AuthorizePage
或[Authorize]
的驗證/授權功能,請對UseAuthentication
和UseAuthorization
進行呼叫:後面,UseRouting
和UseCors
,但是在UseEndpoints
前面:public void Configure(IApplicationBuilder app) { ... app.UseStaticFiles(); app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
以
UseEndpoints
取代UseMvc
或UseSignalR
。如果應用程式使用 CORS 案例,例如
[EnableCors]
,請在使用 CORS 的任何其他中介軟體前面放置對UseCors
的呼叫 (例如,在UseAuthentication
、UseAuthorization
和UseEndpoints
前面放置UseCors
)。以
IWebHostEnvironment
取代IHostingEnvironment
,並且針對 Microsoft.AspNetCore.Hosting 命名空間新增using
陳述式。將
IApplicationLifetime
取代為 IHostApplicationLifetime (Microsoft.Extensions.Hosting 命名空間)。將
EnvironmentName
取代為 Environments (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
、UseAuthorization
和 UseCors
的呼叫必須在對 UseRouting
和 UseEndpoints
的呼叫之間出現才能生效。
健康情況檢查
健康情況檢查會搭配一般主機使用端點路由。 在 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]
屬性可以用來在必要時覆寫預設原則。
在以下範例中:
- CORS 會針對具有
default
具名原則的所有端點啟用。 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 中,需要授權中介軟體。 建議您在 UseAuthentication
後面立即放置 ASP.NET Core 授權中介軟體 (UseAuthorization
)。 授權中介軟體也可以設定為具有預設原則,預設原則可以覆寫。
在 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
獲得授權。 不過,由於 [AllowAnonymous]
,所以 HomeController
允許在沒有使用者登入應用程式的情況下存取:
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute().RequireAuthorization();
});
}
[AllowAnonymous]
public class HomeController : Controller
{
...
}
特定端點的授權
您也可以針對特定端點類別設定授權。 下列程式碼是轉換 MVC 應用程式的範例,將全域 AuthorizeFilter
設定為具有需要授權之特定原則的應用程式:
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
{
或者,可以藉由設定 FallbackPolicy
,將所有端點設定為需要授權,而不需要 [Authorize]
或 RequireAuthorization
。 FallbackPolicy
與 DefaultPolicy
不同。 DefaultPolicy
是由 [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
對應每個中樞。 如同舊版,會明確列出每個中樞。
在下列範例中,會新增 ChatHub
SignalR 中樞的支援:
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 中,該選項現在只會控制在觀察到 backpressure 之前的大小上限。
共用架構中的 SignalR 組件
ASP.NET Core SignalR 伺服器端組件現在會隨 .NET Core SDK 一起安裝。 如需詳細資訊,請參閱本文件中的移除過時的套件參考。
MVC 控制器
控制器的對應現在會在 UseEndpoints
內進行。
如果應用程式使用屬性路由,請新增 MapControllers
。 由於在 ASP.NET Core 3.0 或更新版本中,路由包含許多架構的支援,因此新增屬性路由控制器是選擇性的。
取代下列項目:
- 包含
MapControllerRoute
的MapRoute
- 包含
MapAreaControllerRoute
的MapAreaRoute
由於路由現在包含不僅僅是 MVC 的支援,因此術語已變更,更清楚說明這些方法的用途。 MapControllerRoute
/MapAreaControllerRoute
/MapDefaultControllerRoute
之類的傳統路由會依新增的順序套用。 先放置更具體的路由 (例如區域路由)。
在以下範例中:
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 Pages 現在會在 UseEndpoints
內進行。
如果應用程式使用 Razor Pages,請新增 MapRazorPages
。 由於端點路由包含許多架構的支援,因此新增 Razor Pages 現在是選擇性的。
在下列 Startup.Configure
方法中,MapRazorPages
會新增 Razor Pages 的支援:
public void Configure(IApplicationBuilder app)
{
...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
使用不含端點路由的 MVC
透過 UseMvc
或 UseMvcWithDefaultRoute
在 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
優於 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 中,而且是上述程式碼範例中所見的 webBuilder
類型。 WebHostBuilder 將在未來的版本中淘汰,並由 HostBuilder
取代。
從 WebHostBuilder
到 HostBuilder
的最重大變更是相依性插入 (DI)。 使用 HostBuilder
時,您只能將下列項目插入 Startup
的建構函式中:
HostBuilder
DI 限制式:
- 只讓 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.dll 和 Microsoft.AspNetCore.Authorization.Policy.dll 的應用程式不會受到影響。
未使用 Microsoft.AspNetCore.Authorization.Policy.dll 的應用程式應該執行下列其中一項作業:
- 將參考新增至 Microsoft.AspNetCore.Authorization.Policy.dll。 此方法適用於大部分的應用程式,而且都是必要項目。
- 切換為使用
AddAuthorizationCore
如需詳細資訊,請參閱 AddAuthorization(o =>
) 多載中的中斷性變更位於不同組件 #386。
Identity UI
ASP.NET Core 3.0 的 Identity UI 更新:
- 將套件參考新增至 Microsoft.AspNetCore.Identity.UI。
- 不使用 Razor Pages 的應用程式必須呼叫
MapRazorPages
。 請參閱本文件中的 Razor Pages。 - Bootstrap 4 是預設 UI 架構。 設定
IdentityUIFrameworkVersion
專案屬性以變更預設值。 如需詳細資訊,請參閱此 GitHub 公告。
SignalR
SignalR JavaScript 用戶端已從 @aspnet/signalr
變更為 @microsoft/signalr
。 若要回應這項變更,請變更 package.json
檔案、require
陳述式和 ECMAScript import
陳述式中的參考。
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 或 Visual Studio Code 中的 dotnet-watch,在偵測到對 .cshtml
檔案的變更時重建專案。 在 Visual Studio 中,對專案中 .cs
、.cshtml
或 .razor
檔案的變更會執行 (Ctrl+F5),但是未偵錯 (F5),觸發專案的重新編譯。
若要在 ASP.NET Core 3.0 專案中啟用執行階段編譯:
安裝 Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet 套件。
更新
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 檔案編譯的詳細資訊,請參閱 ASP.NET Core 中的 Razor 檔案編譯。
透過多重目標移轉程式庫
程式庫通常需要支援多個版本的 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]
屬性。 如需詳細資訊,請參閱 [必要] 屬性。
發行
刪除專案目錄中的 bin 和 obj 資料夾。
TestServer
針對直接搭配一般主機使用 TestServer 的應用程式,請在 ConfigureWebHost 中的 IWebHostBuilder 上建立 TestServer
:
[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 變更
檢閱中斷性變更:
- ASP.NET Core 3.0 版本中的中斷性變更完整清單
- 防偽、CORS、診斷、MVC 和路由傳送中的中斷性 API 變更。 此清單包含相容性參數的重大變更。
- 如需 .NET Core、ASP.NET Core 和 Entity Framework Core 之間 2.2 到 3.0 中斷性變更的摘要,請參閱從 2.2 版移轉至 3.0 版的中斷性變更。
使用 catch-all 參數的端點路由
警告
由於路由中的錯誤 (bug),catch-all 參數可能會錯誤比對路由。 受到此錯誤 (bug) 影響的應用程式具有下列特性:
- catch-all 路由,例如
{**slug}"
- catch-all 路由無法比對應該相符的要求。
- 移除其他路由讓 catch-all 路由開始運作。
如需發生此錯誤 (bug) 的範例案例,請參閱 GitHub 錯誤 (bug) 18677 和 16579。
這個錯誤 (bug) 的加入修正包含在 .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 Service 上的 .NET Core 3.0
.NET Core 推出到 Azure App Service 已完成。 所有 Azure App Service 資料中心都可使用 .NET Core 3.0。
ASP.NET Core 模組 (ANCM)
如果在安裝 Visual Studio 時,ASP.NET Core 模組 (ANCM) 不是選取的元件,或者如果系統上已安裝舊版的 ANCM,請下載最新的 .NET Core 裝載套件組合安裝程式 (直接下載),並執行安裝程式。 如需詳細資訊,請參閱裝載組合套件。