如何全局访问当前的 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 对象?的主要内容,如果未能解决你的问题,请参考以下文章

PHP中如何定义全局数组?

sql server中的用户临时表和全局临时表的区别

自动化测试时需要使用python,请问如何理解python中的全局变量和局部变量?

利用Listener实现网站累积访问人数最大同时在线人数当前登录用户数的记录

数据库——创建局部临时表和全局临时表

Qt:从代码中的任何位置访问当前设置文件