【问题标题】:How to access the current HttpRequestMessage object globally?如何全局访问当前的 HttpRequestMessage 对象?
【发布时间】: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?如果您说您的格式化程序在另一个库中,最好不要将它强链接到您的应用程序。
  • 谢谢,我没有使用任何自定义格式化程序。我希望我可以避免传递控制器请求属性。
  • 我终于通过了请求,因为没有更好的解决方案。

标签: c# asp.net-mvc asp.net-web-api asp.net-mvc-routing


【解决方案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的扩展方法。这样,您仍然可以将代码放在单独的类库中,但您的方法将可以访问控制器实例,因此可以访问所有配置信息。

另外,我建议您研究一些针对错误响应的标准化工作,而不是自己发明。

例如:

【讨论】:

  • 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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多