用法指南
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 中,CurrentPrincipal 和 Current 将设置为当前用户。 此功能在 ASP.NET Core 上并非开箱即用。 可通过将 ISetThreadCurrentPrincipal
添加到终结点(可通过 SetThreadCurrentPrincipalAttribute
提供给控制器),使用这些适配器支持此操作。 但是,仅当无法重构代码来消除使用时,才应使用它。
建议:如果可能,请通过调用站点传递 User 或 User 属性,改为使用此属性。 如果不可行,请启用当前用户的设置,并考虑将请求设置为逻辑单线程(请查看下文,了解详细信息)。
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 要求缓冲输出流,例如 Output、End()、Clear() 和 SuppressContent。
建议:为了支持要求在发送之前缓冲响应的 Response 行为,终结点必须通过实现 IBufferResponseStreamMetadata
的终结点元数据选择使用此功能。
若要在所有 MVC 终结点上启用此功能,可按如下所示使用扩展方法:
app.MapDefaultControllerRoute()
.BufferResponseStream();
共享会话状态
为了支持 Session,终结点必须通过实现 ISessionMetadata
的元数据来选择使用此功能。
建议:若要在所有 MVC 终结点上启用此功能,可按如下所示使用扩展方法:
app.MapDefaultControllerRoute()
.RequireSystemWebAdapterSession();
这还需要会话存储的某种实现。 若要详细了解这里的选项,请参阅此处。
远程会话公开额外的终结点供应用程序使用
远程会话支持会公开一个使核心应用能够检索会话信息的终结点。 这可能会导致核心应用和框架应用之间存在一个潜在的长期请求,但它会随着当前请求或会话超时(默认为 20 分钟)而超时。
建议:确保使用的 API 密钥是强密钥,并且与框架应用的连接是通过 SSL 建立的。
框架和核心应用程序的虚拟目录必须是相同的
虚拟目录设置用于系统内的路由生成、授权和其他服务。 此时,由于 ASP.NET Framework 的工作原理,找不到可靠的方法来启用不同的虚拟目录。
建议:确保两个应用程序位于具有相同的应用程序/虚拟目录布局的不同站点(主机和/或端口)上。