用法指南

Microsoft.AspNetCore.SystemWebAdapters 提供一个模拟层来模拟 ASP.NET Core 上 ASP.NET 框架的行为。 下面是关于使用它们时需要注意的一些事项的一些指南:

HttpContext 生存期

适配器由 HttpContext 提供支持,后者在请求生存期结束后不能使用。 因此,在 ASP.NET Core 上运行时,也不能在请求结束后使用 HttpContext,而在 ASP.NET Framework 上时,它有时会正常工作。 如果在请求结束后使用它,会引发 ObjectDisposedException

建议:将所需的值存储到 POCO 中并保留该值。

转换为 HttpContext

有两种方法来将 HttpContext 转换为 HttpContext

  • 隐式转换
  • 构造函数用法

建议:在大多数情况下,应首选隐式强制转换,因为这样会缓存所创建的实例,并确保每个请求只有一个 HttpContext

默认情况下未设置 CurrentCulture

在 ASP.NET Framework 中,已为请求设置 CurrentCulture,但在 ASP.NET Core 中不会自动设置。 相反,必须将相应的中间件添加到管道中。

建议:若要详细了解如何启用此功能,请参阅 ASP.NET Core 本地化

要使用与 ASP.NET Framework 类似的行为启用此功能,最简单的方法是将以下内容添加到管道:

app.UseRequestLocalization();

CurrentPrincipal

在 ASP.NET Framework 中,CurrentPrincipalCurrent 将设置为当前用户。 此功能在 ASP.NET Core 上并非开箱即用。 可通过将 ISetThreadCurrentPrincipal 添加到终结点(可通过 SetThreadCurrentPrincipalAttribute 提供给控制器),使用这些适配器支持此操作。 但是,仅当无法重构代码来消除使用时,才应使用它。

建议:如果可能,请通过调用站点传递 UserUser 属性,改为使用此属性。 如果不可行,请启用当前用户的设置,并考虑将请求设置为逻辑单线程(请查看下文,了解详细信息)。

ASP.NET Core 中不存在请求线程

在 ASP.NET Framework 中,请求具有线程相关性,Current 只有在该线程上时才可用。 ASP.NET Core 不提供这种保证,因此将可在同一异步上下文中使用 Current,但对线程没有保证。

建议:如果读取/写入到 HttpContext,必须确保以单线程方式执行此操作。 可通过设置 ISingleThreadedRequestMetadata,强制要求请求从不在任何异步上下文上并发运行。 这会影响性能,只有在无法重构使用情况来确保非并发访问时才应使用。 有一个实现,可使用 SingleThreadedRequestAttribute 将该实现添加到控制器中:

[SingleThreadedRequest]
public class SomeController : Controller
{
    ...
} 

可能需要预缓冲 Request

默认情况下,传入请求并不总是可查找的,也并非完全可用。 为了在 .NET Framework 中看到行为,可选择对输入流进行预缓冲。 这将完全读取传入流,并将其缓冲到内存或磁盘(具体取决于设置)。

建议:可通过应用实现 IPreBufferRequestStreamMetadata 接口的终结点元数据来启用此功能。 这可用作 PreBufferRequestStreamAttribute 属性,该属性可应用于控制器或方法。

若要在所有 MVC 终结点上启用此功能,可按如下所示使用扩展方法:

app.MapDefaultControllerRoute()
    .PreBufferRequestStream();

Response 可能需要缓冲

Response 上的某些 API 要求缓冲输出流,例如 OutputEnd()Clear()SuppressContent

建议:为了支持要求在发送之前缓冲响应的 Response 行为,终结点必须通过实现 IBufferResponseStreamMetadata 的终结点元数据选择使用此功能。

若要在所有 MVC 终结点上启用此功能,可按如下所示使用扩展方法:

app.MapDefaultControllerRoute()
    .BufferResponseStream();

共享会话状态

为了支持 Session,终结点必须通过实现 ISessionMetadata 的元数据来选择使用此功能。

建议:若要在所有 MVC 终结点上启用此功能,可按如下所示使用扩展方法:

app.MapDefaultControllerRoute()
    .RequireSystemWebAdapterSession();

这还需要会话存储的某种实现。 若要详细了解这里的选项,请参阅此处

远程会话公开额外的终结点供应用程序使用

远程会话支持会公开一个使核心应用能够检索会话信息的终结点。 这可能会导致核心应用和框架应用之间存在一个潜在的长期请求,但它会随着当前请求或会话超时(默认为 20 分钟)而超时。

建议:确保使用的 API 密钥是强密钥,并且与框架应用的连接是通过 SSL 建立的。

框架和核心应用程序的虚拟目录必须是相同的

虚拟目录设置用于系统内的路由生成、授权和其他服务。 此时,由于 ASP.NET Framework 的工作原理,找不到可靠的方法来启用不同的虚拟目录。

建议:确保两个应用程序位于具有相同的应用程序/虚拟目录布局的不同站点(主机和/或端口)上。