在類別庫中使用 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.SdkMicrosoft.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

僅支援伺服器端使用

類別庫很少建置為僅支援伺服器端應用程式。 如果類別庫只需要伺服器端特定功能 (例如存取 CircuitHandlerMicrosoft.AspNetCore.Components.Server.ProtectedBrowserStorage),或使用 ASP.NET Core 特定功能 (例如中介軟體、MVC 控制器或 Razor Pages),請使用下列其中一種方法:

  • 使用 [支援頁面和檢視] 核取方塊 (Visual Studio) 或使用 dotnet new 命令的 -s|--support-pages-and-views 選項建立程式庫時,指定程式庫支援頁面和檢視:

    dotnet new razorclasslib -s
    
  • 除了任何其他必要的 MS Build 屬性之外,只在程式庫的專案檔中提供對 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,則需要:

  • 設定為 trueAddRazorSupportForMvc 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。 請考量下列問題:

  1. 程式庫在功能上是否需要新的 API?
  2. 程式庫可以用不同的方式實作這項功能嗎?

如果程式庫在功能上需要 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>

其他資源