如何全局访问当前的 HttpRequestMessage 对象?
Posted
技术标签:
【中文标题】如何全局访问当前的 HttpRequestMessage 对象?【英文标题】:How to access the current HttpRequestMessage object globally? 【发布时间】:2013-05-16 05:44:46 【问题描述】:我有一个方法可以创建一个包含错误对象的 HttpResponseMessage,该对象将根据当前请求媒体类型格式化程序返回。
目前,我已经对 XmlMediaTypeFormatter 进行了硬编码,但我希望能够在运行时找到当前请求 MediaTypeFormatter,但我无权访问当前请求对象,因为我的以下代码存在于单独的类库中。
private HttpResponseMessage Create(HttpStatusCode statusCode, string errorCode, string errorMessage)
var result = new HttpResponseMessage(statusCode)
Content = new ObjectContent<Error>(new Error()
Code = errorCode,
Message = errorMessage
, new XmlMediaTypeFormatter())
;
return result;
如何全局访问当前的HttpRequestMessage对象?类似 HttpContext.Current.Request
如果不可能,如何实现上述方法,以便知道应该为当前请求使用哪个格式化程序?
【问题讨论】:
为什么不将HttpRequestMessage
传递给您的XmlMediaTypeFormatter
?如果您说您的格式化程序在另一个库中,最好不要将它强链接到您的应用程序。
谢谢,我没有使用任何自定义格式化程序。我希望我可以避免传递控制器请求属性。
我终于通过了请求,因为没有更好的解决方案。
【参考方案1】:
正如我最近发现的那样,这并非不可能。它实际上是添加到当前HttpContext的Items属性中(如果有的话)=[
HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage
编辑:
这是 WebAPI v2 的版本。我不能确定以前的版本。
【讨论】:
WebAPI v1 中没有。 @Magrangs 如果您使用的是 WebAPI 2,那么可以使用。 ASP 管道将消息对象存储在当前 httpcontext 上。您可以自己调试会话并检查HttpContext.Current.Items
中的各种键。请注意,这可能会在 WebAPI 的未来版本中发生变化
另请注意,这不太可能在自托管环境中工作(例如,如果您使用 OWIN 或类似环境),因为不会设置 HttpContext.Current。
@RB。您将如何在自托管环境中完成此任务?
@MehdiDehghani 4 年后,在不同的平台上它不起作用?请告诉【参考方案2】:
为什么不用他们的 CreateResponse 方法做 Web API 团队所做的事情呢?使其成为Controller的扩展方法。这样,您仍然可以将代码放在单独的类库中,但您的方法将可以访问控制器实例,因此可以访问所有配置信息。
另外,我建议您研究一些针对错误响应的标准化工作,而不是自己发明。
例如:
http://www.mnot.net/blog/2013/05/15/http_problem https://datatracker.ietf.org/doc/html/draft-nottingham-http-problem-03 https://github.com/blongden/vnd.error【讨论】:
hmm,如何在运行时从单独的类中获取控制器实例?不认为你的建议可以使用。 您好,感谢您的这篇文章。您能否就目前的情况提供最新信息,说明其中一个是否已获得关注和/或是否已被一个想法(或其他东西)取代?【参考方案3】:您可以尝试使用 Autofac 对其进行归档,例如
public class MyPrincipal : IPrincipal
private readonly IPrincipal principal_;
public MyPrincipal(ILifetimeScope scope)
if (scope.Tag == null || scope.Tag != MatchingScopeLifetimeTags.RequestLifetimeScopeTag)
throw new Exception("Invalid scope");
principal_ = scope.Resolve<HttpRequestMessage>().GetRequestContext().Principal;
这个类可以用 InstancePerRequest 生命周期注册。
builder.RegisterType<MyPrincipal>().As<IPrincipal>().InstancePerRequest();
【讨论】:
以上是关于如何全局访问当前的 HttpRequestMessage 对象?的主要内容,如果未能解决你的问题,请参考以下文章
自动化测试时需要使用python,请问如何理解python中的全局变量和局部变量?