使用类库中的 ASP.NET Core APIUse ASP.NET Core APIs in a class library

本文内容

作者:Scott Addie

此文档提供了关于如何使用类库中的 ASP.NET Core API 的指南。若要查看所有其他的库指南,请参阅开放源代码库指南

确定要支持哪些 ASP.NET Core 版本Determine which ASP.NET Core versions to support

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 共享框架Use the ASP.NET Core shared framework

随着 .NET Core 3.0 发布,许多 ASP.NET Core 程序集不再作为包发布到 NuGet。而是改为将这些程序集包含在通过 .NET Core SDK 和运行时安装程序安装的 Microsoft.AspNetCore.App 共享框架中。若要查看不再发布的包列表,请参阅删除过时的包引用

自 .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> 元素添加到项目文件:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  7. </ItemGroup>
  8. </Project>

仅面向 .NET Core 3.x 的项目支持使用此方式引用 ASP.NET Core。

包含 Blazor 扩展性Include Blazor extensibility

Blazor 支持 WebAssembly (WASM) 和服务器托管模型除非出于特定原因无法实现支持,否则 Razor 组件库应同时支持这两种托管模型。Razor 组件库必须使用 Microsoft.NET.Sdk.Razor SDK

同时支持两种托管模型Support both hosting models

请按照适合你的编辑器的以下说明操作,以同时支持 Blazor 服务器Blazor WASM 项目的 Razor 组件消耗。

使用“Razor 类库”项目模板 。应取消选中此模板的“支持页和视图”复选框。

在“集成终端”中运行以下命令:

  1. dotnet new razorclasslib

使用“Razor 类库”项目模板 。

模板生成的项目执行以下操作:

例如:

  1. <Project Sdk="Microsoft.NET.Sdk.Razor">
  2. <PropertyGroup>
  3. <TargetFrameworks>netstandard2.0</TargetFrameworks>
  4. <RazorLangVersion>3.0</RazorLangVersion>
  5. </PropertyGroup>
  6. <ItemGroup>
  7. <PackageReference Include="Microsoft.AspNetCore.Components" Version="3.0.0" />
  8. <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.0.0" />
  9. </ItemGroup>
  10. </Project>

支持特定托管模型Support a specific hosting model

支持单个 Blazor 托管模型的情况并不常见。例如,完成以下操作可仅支持 Blazor 服务器项目的 Razor 组件消耗:

  • 面向 .NET Core 3.x。
  • 添加针对共享框架的 <FrameworkReference> 元素。

例如:

  1. <Project Sdk="Microsoft.NET.Sdk.Razor">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  7. </ItemGroup>
  8. </Project>

有关包含 Razor 组件的库的详细信息,请参阅 ASP.NET Core Razor 组件类库

包括 MVC 扩展性Include MVC extensibility

此部分概述了针对包括以下内容的库的建议:

此部分未探讨用于支持多个 MVC 版本的多目标。若要查看关于支持多个 ASP.NET Core 版本的指南,请参阅支持多个 ASP.NET Core 版本

Razor 视图或 Razor PagesRazor views or Razor Pages

包括 Razor 视图Razor Pages 的项目必须使用 Microsoft.NET.Sdk.Razor SDK

若项目面向 .NET Core 3.x,它必须满足以下要求:

  • AddRazorSupportForMvc MSBuild 属性设置为 true
  • 具有针对共享框架的 <FrameworkReference> 元素。

“Razor 类库”项目模板符合针对面向 .NET Core 3.x 的项目的上述要求。 请针对自己的编辑器使用以下说明。

使用“Razor 类库”项目模板 。应选中此模板的“支持页和视图”复选框。

在“集成终端”中运行以下命令:

  1. dotnet new razorclasslib -s

此时无任何项目模板支持。

例如:

  1. <Project Sdk="Microsoft.NET.Sdk.Razor">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.0</TargetFramework>
  4. <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  5. </PropertyGroup>
  6. <ItemGroup>
  7. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  8. </ItemGroup>
  9. </Project>

若项目改为面向 .NET Standard,则需要 Microsoft.AspNetCore.Mvc 包引用。Microsoft.AspNetCore.Mvc 包移到了 ASP.NET Core 3.0 的共享框架中,因此不再发布。例如:

  1. <Project Sdk="Microsoft.NET.Sdk.Razor">
  2. <PropertyGroup>
  3. <TargetFramework>netstandard2.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  7. </ItemGroup>
  8. </Project>

标记帮助程序Tag Helpers

包含标记帮助器的项目应使用 Microsoft.NET.Sdk SDK。若面向 .NET Core 3.x,则添加针对共享框架的 <FrameworkReference> 元素。例如:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  7. </ItemGroup>
  8. </Project>

若面向 .NET Standard(以支持 ASP.NET Core 3.x 之前的版本),则添加 Microsoft.AspNetCore.Mvc.Razor 的包引用。Microsoft.AspNetCore.Mvc.Razor 包移到了共享框架,因此不再发布。例如:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFramework>netstandard2.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  7. </ItemGroup>
  8. </Project>

视图组件View components

包含视图组件的项目应使用 Microsoft.NET.Sdk SDK。若面向 .NET Core 3.x,则添加针对共享框架的 <FrameworkReference> 元素。例如:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  7. </ItemGroup>
  8. </Project>

若面向 .NET Standard(以支持 ASP.NET Core 3.x 之前的版本),则添加 Microsoft.AspNetCore.Mvc.ViewFeatures 的包引用。Microsoft.AspNetCore.Mvc.ViewFeatures 包移到了共享框架,因此不再发布。例如:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFramework>netstandard2.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
  7. </ItemGroup>
  8. </Project>

支持多个 ASP.NET Core 版本Support multiple ASP.NET Core versions

创作支持多个 ASP.NET Core 变体的库需要多目标。以下列情况为例:标记帮助器库必须支持以下 ASP.NET Core 变体:

  • 面向 .NET Framework 4.6.1 的 ASP.NET Core 2.1
  • 面向 .NET Core 2.x 的 ASP.NET Core 2.x
  • 面向 .NET Core 3.x 的 ASP.NET Core 3.x

以下项目文件通过 TargetFrameworks 属性支持这些变体:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net461</TargetFrameworks>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <PackageReference Include="Markdig" Version="0.16.0" />
  7. </ItemGroup>
  8. <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.0'">
  9. <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  10. </ItemGroup>
  11. <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
  12. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  13. </ItemGroup>
  14. </Project>

上面的项目文件将完成以下操作:

  • 为所有使用者添加 Markdig 包。
  • 为面向 .NET Framework 4.6.1 或更高版本或者 .NET Core 2.x 的使用者添加 Microsoft.AspNetCore.Mvc.Razor 的引用。由于向后兼容性,此包的版本 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:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFrameworks>netstandard2.0;netcoreapp3.0</TargetFrameworks>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <PackageReference Include="Markdig" Version="0.16.0" />
  7. </ItemGroup>
  8. <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.0'">
  9. <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  10. </ItemGroup>
  11. <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
  12. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  13. </ItemGroup>
  14. </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。有关详细信息,请参阅多目标

使用未变更的 APIUse an API that hasn't changed

以下面的情况为例:你要将中间件库从 .NET Core 2.2 升级到 3.0。库正在使用的 ASP.NET Core 中间件 API 尚未从 ASP.NET Core 2.2 变更到 3.0。若要继续让 .NET Core 3.0 支持此中间件库,请执行以下步骤:

  • 按照标准库指南操作。
  • 若共享框架中不存在相应的程序集,则添加针对每个 API 的 NuGet 包的包引用。

使用已变更的 APIUse an API that changed

以下面的情况为例:你要将库从 .NET Core 2.2 升级到 .NET Core 3.0。库正在使用的 ASP.NET Core API 包含 ASP.NET Core 3.0 的中断性变更请考虑此库是否可以重写为不使用所有版本中已损坏的 API。

若可以重写此库,则进行重写,并通过包引用继续面向早期版本的目标框架(例如 .NET Standard 2.0 或 .NET Framework 4.6.1)。

若无法重写此库,则执行以下步骤:

  • 添加针对 .NET Core 3.0 的目标。
  • 添加针对共享框架的 <FrameworkReference> 元素。
  • 结合使用 #if 预处理器指令和对应的目标框架符号,以进行有条件的代码编译。

例如,自 ASP.NET Core 3.0 起默认不可对 HTTP 请求和响应流进行同步读写。默认情况下,ASP.NET Core 2.2 支持同步行为。以发生 IO 时应可以进行同步读取的中间件库为例。此库应将用于启用同步功能的代码括在相应的预处理器指令中。例如:

  1. public async Task Invoke(HttpContext httpContext)
  2. {
  3. if (httpContext.Request.Path.StartsWithSegments(_path, StringComparison.Ordinal))
  4. {
  5. httpContext.Response.StatusCode = 200;
  6. httpContext.Response.ContentType = "application/json";
  7. httpContext.Response.ContentLength = _bufferSize;
  8. #if !NETCOREAPP3_0 && !NETCOREAPP5_0
  9. var syncIOFeature = httpContext.Features.Get<IHttpBodyControlFeature>();
  10. if (syncIOFeature != null)
  11. {
  12. syncIOFeature.AllowSynchronousIO = true;
  13. }
  14. using (var sw = new StreamWriter(
  15. httpContext.Response.Body, _encoding, bufferSize: _bufferSize))
  16. {
  17. _json.Serialize(sw, new JsonMessage { message = "Hello, World!" });
  18. }
  19. #else
  20. await JsonSerializer.SerializeAsync<JsonMessage>(
  21. httpContext.Response.Body, new JsonMessage { message = "Hello, World!" });
  22. #endif
  23. return;
  24. }
  25. await _next(httpContext);
  26. }

使用 3.0 引入的 APIUse an API introduced in 3.0

假设你想要使用 ASP.NET Core 3.0 引入的 ASP.NET Core API。请考虑下列问题:

  • 此库在功能上是否需要此新 API?
  • 库是否可以通过其他方式实现此功能?
    若此库在功能上需要此 API,并且没有实现它的下层方法:
  • 仅面向 .NET Core 3.x。
  • 添加针对共享框架的 <FrameworkReference> 元素。

若此库可以通过其他方式实现此功能:

  • 将 .NET Core 3.x 添加为目标框架。
  • 添加针对共享框架的 <FrameworkReference> 元素。
  • 结合使用 #if 预处理器指令和对应的目标框架符号,以进行有条件的代码编译。

例如,以下标记帮助器使用 ASP.NET Core 3.0 引入的 IWebHostEnvironment 接口。面向 .NET Core 3.0 的使用者执行 NETCOREAPP3_0 目标框架符号定义的代码路径。对于 .NET Core 2.1 和 .NET Framework 4.6.1 使用者,标记帮助器的构造函数参数类型更改为 IHostingEnvironment此更改很有必要,因为 ASP.NET Core 3.0 将 IHostingEnvironment 标记为过时,并推荐将 IWebHostEnvironment 作为替代项。

  1. [HtmlTargetElement("script", Attributes = "asp-inline")]
  2. public class ScriptInliningTagHelper : TagHelper
  3. {
  4. private readonly IFileProvider _wwwroot;
  5. #if NETCOREAPP3_0
  6. public ScriptInliningTagHelper(IWebHostEnvironment env)
  7. #else
  8. public ScriptInliningTagHelper(IHostingEnvironment env)
  9. #endif
  10. {
  11. _wwwroot = env.WebRootFileProvider;
  12. }
  13. // code omitted for brevity
  14. }

以下多目标项目文件支持此标记帮助器方案:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFrameworks>netcoreapp2.1;netcoreapp3.0;net461</TargetFrameworks>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <PackageReference Include="Markdig" Version="0.16.0" />
  7. </ItemGroup>
  8. <ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.0'">
  9. <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor" Version="2.1.0" />
  10. </ItemGroup>
  11. <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
  12. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  13. </ItemGroup>
  14. </Project>

使用共享框架已删除的 APIUse an API removed from the shared framework

若要使用共享框架已删除的 ASP.NET Core 程序集,请添加相应的包引用。若要查看 ASP.NET Core 3.0 的共享框架已删除的包列表,请参阅删除过时的包引用

例如,添加 Web API 客户端:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.0</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <FrameworkReference Include="Microsoft.AspNetCore.App" />
  7. </ItemGroup>
  8. <ItemGroup>
  9. <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
  10. </ItemGroup>
  11. </Project>

其他资源Additional resources