在類別庫中使用 ASP.NET Core API
作者:Scott Addie
本文件提供在類別庫中使用 ASP.NET Core API 的指引。 如需所有其他程式庫指引,請參閱開放原始碼程式庫指導。
判斷要支援的 ASP.NET Core 版本
ASP.NET Core 遵守 .NET Core 支援原則。 在判斷程式庫中要支援的 ASP.NET Core 版本時,請參閱支援原則。 程式庫應該遵守以下原則:
- 盡力支援分類為長期支援 (LTS) 的所有 ASP.NET Core 版本。
- 沒有義務支援分類為生命週期結束 (EOL) 的 ASP.NET Core 版本。
隨著 ASP.NET Core 預覽版本的推出,中斷性變更將張貼到 aspnet/Announcements GitHub 存放庫。 在開發架構功能時,可以對程式庫進行相容性測試。
使用 ASP.NET Core 共用架構
隨著 .NET Core 3.0 的發行,許多 ASP.NET Core 組件不再作為套件發佈至 NuGet。 相反地,這些組件會包含在 Microsoft.AspNetCore.App
共用架構中,該架構隨 .NET Core SDK 和執行階段安裝程式一起安裝。 如需不再發佈的套件清單,請參閱移除過時的套件參考。
自 .NET Core 3.0 起,使用 Microsoft.NET.Sdk.Web
MSBuild SDK 的專案會以隱含方式參考共用架構。 使用 Microsoft.NET.Sdk
或 Microsoft.NET.Sdk.Razor
SDK 的專案必須參考 ASP.NET Core,才能在共用架構中使用 ASP.NET Core API。
若要參考 ASP.NET Core,請將下列 <FrameworkReference>
元素新增至您的專案檔中:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
包含 Blazor 擴充性
Blazor 支援為伺服器端和用戶端應用程式建立 Razor 元件類別庫。 若要支援類別庫中的 Razor 元件,類別庫必須使用 Microsoft.NET.Sdk.RazorSDK。
支援伺服器端和用戶端應用程式
若要支援伺服器端和用戶端應用程式從單一程式庫使用 Razor 元件,請使用下列編輯器指示。
使用 Razor 類別庫專案範本。
注意
請勿選取 [支援頁面和檢視] 核取方塊。 選取該核取方塊會產生只支援伺服器端應用程式的類別庫。
從專案範本產生的程式庫,將:
- 基於已安裝的 SDK,將目標指向目前的 .NET 架構。
- 啟用瀏覽器相容性檢查來檢查平台相依性,方法是透過將
browser
作為支援的平台包含在SupportedPlatform
MSBuild 項目中。 - 新增 Microsoft.AspNetCore.Components.Web 的 NuGet 套件參考。
RazorClassLibrary-CSharp.csproj
(參考來源)
注意
.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤。
支援多個架構版本
如果程式庫必須支援目前版本中新增至 Blazor 的功能,同時還支援一個以上舊版本,請對該程式庫進行多目標指向。 在 TargetFrameworks
MSBuild 屬性中,提供以分號分隔的目標 Framework Moniker (TFM) 清單:
<TargetFrameworks>{TARGET FRAMEWORKS}</TargetFrameworks>
在上述範例中,{TARGET FRAMEWORKS}
預留位置代表以分號分隔的 TFM 清單。 例如: netcoreapp3.1;net5.0
。
僅支援伺服器端使用
類別庫很少建置為僅支援伺服器端應用程式。 如果類別庫只需要伺服器端特定功能 (例如存取 CircuitHandler 或 Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage),或使用 ASP.NET Core 特定功能 (例如中介軟體、MVC 控制器或 Razor Pages),請使用下列其中一種方法:
使用 [支援頁面和檢視] 核取方塊 (Visual Studio) 或使用
dotnet new
命令的-s|--support-pages-and-views
選項建立程式庫時,指定程式庫支援頁面和檢視:dotnet new razorclasslib -s
除了任何其他必要的 MSBuild 屬性之外,只在程式庫的專案檔中提供對 ASP.NET Core 的架構參考:
<ItemGroup> <FrameworkReference Include="Microsoft.AspNetCore.App" /> </ItemGroup>
如需關於包含 Razor 元件之程式庫的詳細資訊,請參閱從 Razor 類別庫 (RCL) 取用 ASP.NET Core Razor 元件。
包含 MVC 擴充性
本節概述對程式庫的建議,包括:
本部分不討論支援多個 MVC 版本的多目標指向。 如需支援多個 ASP.NET Core 版本的指引,請參閱支援多個 ASP.NET Core 版本。
Razor 檢視或 Razor Pages
包含 Razor 檢視或 Razor Pages 的專案必須使用 Microsoft.NET.Sdk.RazorSDK。
如果專案將目標指向 .NET Core 3.x,則需要:
- 設定為
true
的AddRazorSupportForMvc
MSBuild 屬性。 - 共用架構的
<FrameworkReference>
元素。
Razor 類別庫專案範本符合將目標指向 .NET Core 之專案的上述需求。 請使用下列編輯器指示。
使用 Razor 類別庫專案範本。 務必選取範本的 [支援頁面和檢視] 核取方塊。
例如:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
如果專案改為將目標指向 .NET Standard,則需要 Microsoft.AspNetCore.Mvc 套件參考。 Microsoft.AspNetCore.Mvc
套件已移至 ASP.NET Core 3.0 中的共用架構中,因此不再發佈。 例如:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
</ItemGroup>
</Project>
標籤協助程式
包含標記協助程式的專案應該使用 Microsoft.NET.Sdk
SDK。 如果將目標指向 .NET Core 3.x,請為共用架構新增一個 <FrameworkReference>
元素。 例如:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
如果將目標指向 .NET Standard (以支援 ASP.NET Core 3.x 之前的版本),請新增對 Microsoft.AspNetCore.Mvc.Razor 的套件參考。 Microsoft.AspNetCore.Mvc.Razor
套件已移至共用架構中,因此不再發佈。 例如:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
</ItemGroup>
</Project>
檢視元件
包含檢視元件的專案應該使用 Microsoft.NET.Sdk
SDK。 如果將目標指向 .NET Core 3.x,請為共用架構新增一個 <FrameworkReference>
元素。 例如:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
如果將目標指向 .NET Standard (以支援 ASP.NET Core 3.x 之前的版本),請新增對 Microsoft.AspNetCore.Mvc.ViewFeatures 的套件參考。 Microsoft.AspNetCore.Mvc.ViewFeatures
套件已移至共用架構中,因此不再發佈。 例如:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
</ItemGroup>
</Project>
支援多個 ASP.NET Core 版本
需要多目標指向,才能撰寫支援 ASP.NET Core 的多個變體的程式庫。 請考慮其中標記協助程式程式庫必須支援下列 ASP.NET Core 變體的情況:
- 將目標指向 .NET Framework 4.6.1 的 ASP.NET Core 2.1
- 將目標指向 .NET Core 2.x 的 ASP.NETCore 2.x
- 將目標指向 .NET Core 3.x 的 ASP.NETCore 3.x
下列專案檔透過 TargetFrameworks
屬性支援這些變體:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.16.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
使用上述專案檔,可以:
- 為所有取用者新增
Markdig
套件。 - Microsoft.AspNetCore.Mvc.Razor 的參考會新增給以 .NET Framework 4.6.1 或更新版本或 .NET Core 2.x 為目標的取用者。 由於回溯相容性,該套件的 2.1.0 版本適用於 ASP.NET Core 2.2。
- 共用架構可供將目標指向 .NET Core 3.x 的取用者參考。 套件
Microsoft.AspNetCore.Mvc.Razor
包含在共用架構中。
或者,可以將目標指向 .NET Standard 2.0,而不是同時將目標指向 .NET Core 2.1 和 .NET Framework 4.6.1:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.16.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
使用上述專案檔時,請注意以下事項:
- 由於程式庫只包含標記協助程式,因此會更直接了當地將目標指向執行 ASP.NET Core 的特定平台:.NET Core 和 .NET Framework。 其他 .NET Standard 2.0 相容的目標架構 (例如 Unity、UWP 和 Xamarin) 無法使用標記協助程式。
- 使用 .NET Framework 中的 .NET Standard 2.0,會有一些在 .NET Framework 4.7.2 中已經解決的問題。 您可以透過將目標指向 .NET Framework 4.6.1,來改善使用 .NET Framework 4.6.1 到 4.7.1 的取用者體驗。
如果您的程式庫需要呼叫平台特定 API,請將目標指向特定的 .NET 實作,而不是 .NET Standard。 如需詳細資訊,請參閱多重目標。
使用未變更的 API
假設您要將中介軟體程式庫從 .NET Core 2.2 升級至 3.1。 程式庫中使用的 ASP.NET Core 中介軟體 API,在 ASP.NET Core 2.2 和 3.1 之間並未變更。 若要繼續支援 .NET Core 3.1 中的中介軟體程式庫,請執行下列步驟:
- 遵循標準程式庫指導方針。
- 如果共用架構中不存在對應的組件,請為每個 API 的 NuGet 套件新增套件參考。
使用已變更的 API
假設您要將程式庫從 .NET Core 2.2 升級至 .NET Core 3.1。 程式庫中使用的 ASP.NET Core API,在 ASP.NET Core 3.1 發生中斷性變更。 請考慮是否可以重寫該程式庫,請不要在任何版本中使用已中斷的 API。
如果可以重寫該程式庫,請這樣做,並繼續搭配套件參考將目標指向先前的目標架構 (例如,.NET Standard 2.0 或 .NET Framework 4.6.1)。
如果您無法重寫該程式庫,請執行下列步驟:
- 為 .NET Core 3.1 新增目標。
- 為共用架構新增
<FrameworkReference>
元素。 - 使用 #if 前置處理器指示詞搭配適當的目標架構符號,有條件地編譯程式碼。
例如,自 ASP.NET Core 3.1 起,預設會停用 HTTP 要求和回應資料流上的同步讀取和寫入。 ASP.NET Core 2.2 預設支援同步行為。 請考慮使用中介軟體程式庫,其中在發生 I/O 時應該啟用同步讀取和寫入。 該程式庫應該將程式碼包含在適當的前置處理器指示詞中,以啟用同步功能。 例如:
public async Task Invoke(HttpContext httpContext)
{
if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
{
httpContext.Response.StatusCode = (int) HttpStatusCode.OK;
httpContext.Response.ContentType = "application/json";
httpContext.Response.ContentLength = _bufferSize;
#if !NETCOREAPP3_1 && !NETCOREAPP5_0
var syncIOFeature = httpContext.Features.Get<IHttpBodyControlFeature>();
if (syncIOFeature != null)
{
syncIOFeature.AllowSynchronousIO = true;
}
using (var sw = new StreamWriter(
httpContext.Response.Body, _encoding, bufferSize: _bufferSize))
{
_json.Serialize(sw, new JsonMessage { message = "Hello, World!" });
}
#else
await JsonSerializer.SerializeAsync<JsonMessage>(
httpContext.Response.Body, new JsonMessage { message = "Hello, World!" });
#endif
return;
}
await _next(httpContext);
}
使用 3.1 中引入的 API
假設您想要使用 ASP.NET Core 3.1 中引入的 ASP.NET Core API。 請考量下列問題:
- 程式庫在功能上是否需要新的 API?
- 程式庫可以用不同的方式實作這項功能嗎?
如果程式庫在功能上需要 API,而且無法向下實作:
- 僅將目標指向 .NET Core 3.x。
- 為共用架構新增
<FrameworkReference>
元素。
如果程式庫可以用不同的方式實作該功能:
- 新增 .NET Core 3.x 作為目標架構。
- 為共用架構新增
<FrameworkReference>
元素。 - 使用 #if 前置處理器指示詞搭配適當的目標架構符號,有條件地編譯程式碼。
例如,下列標記協助程式使用 ASP.NET Core 3.1 中引入的 IWebHostEnvironment 介面。 將目標指向 .NET Core 3.1 的取用者,會執行由 NETCOREAPP3_1
目標架構符號定義的程式碼路徑。 對於 .NET Core 2.1 和 .NET Framework 4.6.1 取用者,標記協助程式的建構函式參數型別會變更為 IHostingEnvironment。 這是必要的變更,因為 ASP.NET Core 3.1 已將 IHostingEnvironment
標記為已淘汰,並建議使用 IWebHostEnvironment
作為取代項目。
[HtmlTargetElement("script", Attributes = "asp-inline")]
public class ScriptInliningTagHelper : TagHelper
{
private readonly IFileProvider _wwwroot;
#if NETCOREAPP3_1
public ScriptInliningTagHelper(IWebHostEnvironment env)
#else
public ScriptInliningTagHelper(IHostingEnvironment env)
#endif
{
_wwwroot = env.WebRootFileProvider;
}
// code omitted for brevity
}
下列多目標指向專案檔支援此標記協助程式案例:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1;net461</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.16.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
使用自共用架構中移除的 API
若要使用已自共用架構中移除的 ASP.NET Core 組件,請新增適當的套件參考。 如需已自 ASP.NET Core 3.1 的共用架構中移除的套件清單,請參閱移除過時的套件參考。
例如,若要新增 Web API 用戶端:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
</ItemGroup>
</Project>