C# 如何全局访问当前的 HttpRequestMessage 对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16670329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 01:38:06  来源:igfitidea点击:

How to access the current HttpRequestMessage object globally?

c#asp.net-mvcasp.net-web-apiasp.net-mvc-routing

提问by The Light

I have a method which creates an HttpResponseMessage containing an Error object which will be returned based on the current request media type formatter.

我有一个方法可以创建一个包含 Error 对象的 HttpResponseMessage ,该对象将根据当前的请求媒体类型格式化程序返回。

Currently, I have hardcoded the XmlMediaTypeFormatter but I'd like to be able to find the current request MediaTypeFormatter at runtime but I don't have access to the current request object since my below code exists on a separate class library.

目前,我对 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;
}

How to access the current HttpRequestMessage object globally? something like HttpContext.Current.Request

如何全局访问当前的 HttpRequestMessage 对象?类似于 HttpContext.Current.Request

If impossible, how to implement the above method so that it knows which formatter it should be using for the current request?

如果不可能,如何实现上述方法,以便它知道应该为当前请求使用哪个格式化程序?

回答by Darrel Miller

Why not do what the Web API team have done with their CreateResponse method? Make it an extension method of Controller. That way you can still have the code in a separate class library, but your method will have access to the controller instance and therefore all the Configuration information.

为什么不做 Web API 团队用他们的 CreateResponse 方法所做的事情呢?使其成为Controller的扩展方法。这样,您仍然可以将代码放在单独的类库中,但您的方法将可以访问控制器实例,因此可以访问所有配置信息。

And on a slightly different note, I would suggest you look into some of the standardization efforts for error responses rather than inventing your own.

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

e.g.:

例如:

回答by dariusc

It's not impossible as I have just recently found out. It's actually added into the Items property of the current HttpContext (if there is one) =[

这并非不可能,因为我最近才发现。它实际上是添加到当前 HttpContext 的 Items 属性中的(如果有的话)=[

HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage

Edit:

编辑:

This is as of WebAPI v2 .. I cannot be sure of previous versions.

这是 WebAPI v2 .. 我不能确定以前的版本。

回答by Lonli-Lokli

You can try to archieve it with Autofac, eg

您可以尝试使用 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;
        }
}

This class can be registred with InstancePerRequest lifetime.

此类可以使用 InstancePerRequest 生命周期注册。

   builder.RegisterType<MyPrincipal>().As<IPrincipal>().InstancePerRequest();