c# - 通过静态类访问 HttpContext 可以“正确”处理不同的请求
问题描述
我在尝试解决需要非控制器中的一些标头的问题时发现了这篇文章。
我对这种方法持怀疑态度,作者没有回应。我主要关心的是拥有全局静态的方法HttpContext
。我在想它不应该处理两个请求。下面是这种情况的一个示例(连同我提到的文章中介绍的方法):
public static class AppContext
{
public static IHttpContextAccessor HttpContextAccessor { get; set; }
public static void Configure(IHttpContextAccessor accessor)
{
HttpContextAccessor = accessor;
}
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
IHttpContextAccessor contextAccessor)
{
AppContext.Configure(contextAccessor);
...
}
[Route("api/[controller]")]
[ApiController]
public class ExampleController : ControllerBase
{
[HttpGet("{number}")]
public IActionResult Example(int number)
{
if (number == 1)
{
Thread.Sleep(10000);
}
var result = AppContext.HttpContextAccessor.HttpContext.Request.GetDisplayUrl();
return Ok(result + " " + number);
}
}
想提一下,作者为这个静态类使用了名称App Context,这正是我所期望的(那时它确实没用)。
但是,让我感到困惑的是实际行为。我正在调试将断点放置在var result = ...
. 我首先发送一个number
= 1 的请求,它会休眠一段时间,然后我发送第二个请求,它的值不同number
。我跳过为第一个请求放置的断点并等待第一个请求(number
= 1)停在那里。然后我检查GetDisplayUrl()
返回的内容 - 它返回一个路径/1
(这确实是这个请求的路径,它已经休眠了 10 秒)。我希望它以静态类/2
的静态字段结尾IHttpContextAccessor
AppContext
已被ConfigureServices()
方法中的第二个请求重写。
我相信我遗漏了一些重要的东西,如果你也提供一些我(和其他人困惑的)可以用来填补空白的资源,我会很高兴。
您能否也给我一些有关使用该方法的更多见解?可测试性是否受到影响(因为我在应用程序中的任何地方都使用静态类)以及以何种方式受到影响?
解决方案
这里发生了一些事情。从技术上讲,这将起作用,仅仅是因为IHttpContextAccessor
它是一个单例。因此,将它持久保存在静态 ivar 上在技术上没有任何问题。无论哪种方式,它都会持续应用程序的生命周期。
HttpContext
本身是有范围的,但这不是这里设置的。因此,只要您有权访问IHttpContextAccessor
,您就可以在技术上访问HttpContext
,尽管它可能为空,具体取决于您尝试访问的位置(即在请求管道之外)。
然而,这只是一种糟糕的做法,甚至都不好笑。对于好的代码,应该在很大程度上避免静态。它们是不可测试的,它们用于隐藏依赖关系,使您的代码更难理解和更脆弱。
我见过一些人做类似的事情,但那是为了让HttpContext
自己看起来好像是静态的,目的只是支持假设为 static 的遗留代码HttpContext
。该解决方案对此无济于事,因为您必须以任何一种方式更改遗留代码。因此,它完全没有用。
如果您需要访问HttpContext
它本质上存在的地方(例如控制器、页面和视图)之外的地方,那么只需IHttpContextAccessor
在那里注入并直接使用它。这整件事AppContext
是个笑话,应该在火中死去。
推荐阅读
- watson-assistant - How to save user response in DB or External System in watson assistant
- javascript - 在 jquery 中使用 window.location.href 时如何在同一页面上重定向?
- arrays - 如何在循环中设置数组 useState 以在默认数组中添加更多项目?
- nativescript - 如何调整从 nativescript-imagepicker 插件中挑选的图像大小
- azure-devops - 将 NuGet 包从 TeamCity 发布到 Azure DevOps Artifacts
- windows - 如何使用脚本获取 Windows SE RDP 和 CONSOLE?
- android - 在视图寻呼机内更新适配器中的项目
- keras - 用于回归的多输入(文本和数字)模型,给出相同的输出
- python - 在Django中查询多个外键
- python - 自动颜色 seaborn 堆积条形图