【问题标题】:How do I convert an HttpRequestBase into an HttpRequest object?如何将 HttpRequestBase 转换为 HttpRequest 对象?
【发布时间】:2010-11-29 23:11:10
【问题描述】:

在我的 ASP.NET MVC 控制器中,我有一个需要 HttpRequest 对象的方法。我只能访问一个 HttpRequestBase 对象。

无论如何我可以以某种方式转换它吗?

我可以/应该做什么??

【问题讨论】:

标签: asp.net-mvc httprequest


【解决方案1】:

通常,当您需要在控制器操作中访问 HttpContext 属性时,您可以在设计方面做得更好。

例如,如果您需要访问当前用户,请为您的操作方法提供IPrincipal 类型的参数,您可以使用Attribute 填充该参数,并在测试时根据需要进行模拟。有关如何操作的小示例,请参阅this blog post,特别是第 7 点。

【讨论】:

  • 完全同意!问题是,我无法修改我们需要使用的当前类库..所以这对我没有多大帮助:(
【解决方案2】:

是你的方法,所以你可以重写它来取HttpRequestBase?如果没有,您始终可以从HttpContext.Current.HttpRequest 获取当前的HttpRequest 以传递。但是,我经常将对 HttpContext 的访问封装在 ASP.NET: Removing System.Web Dependencies 中提到的类中,以获得更好的单元测试支持。

【讨论】:

  • 不好意思,我也想到了这个,还是不行。 HttpContext 是 MVC 上下文 .. 所以没有暴露在它上面的“当前”属性。我不确定如何访问'oldschool' HttpContext.Current ... ???
  • 为确保您获取的是 HttpContext 类而不是控制器成员,请尝试使用 System.Web.HttpContext.Current。
  • 我需要使用完整的命名空间,因为它使用了当前的 MVC 命名空间属性。干杯。其他人注意:不要做我正在做的事情。这是一个非常糟糕的事情(tm)。
  • 链接已失效; developmentalmadness.com 域名已过期,现在是 GoDaddy 填充页面
  • System.Web.HttpContext.Current.Request
【解决方案3】:

尝试使用您的 HttpRequestBase 来使用/创建一个 HttpRequestWrapper。

【讨论】:

    【解决方案4】:

    正如凯文所说的那样。

    我使用静态方法来检索HttpContext.Current.Request,因此总是有一个HttpRequest 对象以供需要时使用。

    在类助手中

    public static HttpRequest GetRequest()
    {
        return HttpContext.Current.Request;
    }
    

    在控制器中

    if (AcessoModel.UsuarioLogado(Helper.GetRequest()))
    

    在此查看

    bool bUserLogado = ProjectNamespace.Models.AcessoModel.UsuarioLogado(
                          ProjectNamespace.Models.Helper.GetRequest()
                       );
    
    if (bUserLogado == false) { Response.Redirect("/"); }
    

    我的方法 UsuarioLogado

    public static bool UsuarioLogado(HttpRequest Request)
    

    【讨论】:

      【解决方案5】:

      没有办法在这些类型之间进行转换。

      我们有一个类似的案例。我们重写了我们的类/Web 服务方法,以便它们使用 HttpContextBase、HttpApplicationStateBase、HttpServerUtilityBase、HttpSessionStateBase... 而不是没有“Base”后缀的关闭名称类型(HttpContext,... HttpSessionState)。使用自制的 mock 更容易处理。

      很抱歉你没能做到。

      【讨论】:

      • 不正确。var httpRequest = Context.Request; var httpRequestBase = new HttpRequestWrapper(Context.Request);
      【解决方案6】:

      您应该始终在应用程序中使用 HttpRequestBase 和 HttpResponseBase,而不是无法测试的具体版本(没有 typemock 或其他魔法)。

      只需使用HttpRequestWrapper类进行转换,如下所示。

      var httpRequestBase = new HttpRequestWrapper(Context.Request);
      

      【讨论】:

      • 另外注意,不仅可以使用HttpRequestBaseHttpResponseBase,还可以使用HttpContextBase。 :)
      • 这是在错误的方向转换。问题是:如果我一个HttpRequestBase,我如何得到一个实际的HttpRequest
      【解决方案7】:

      你可以使用

      System.Web.HttpContext.Current.Request
      

      这里的关键是您需要完整的命名空间才能访问“正确的”HttpContext。

      我知道这个问题被问到已经 4 年了,但是如果这对某人有帮助,那么你就去吧!

      (编辑:我看到 Kevin Hakanson 已经给出了这个答案......所以希望我的回答能帮助那些只阅读答案而不是 cmets 的人。):)

      【讨论】:

        【解决方案8】:

        这是一个 ASP.Net MVC 3.0 AsyncController,它接受请求,将入站 HttpRequestBase MVC 对象转换为 System.Web.HttpWebRequest。然后它异步发送请求。当响应返回时,它将 System.Web.HttpWebResponse 转换回 MVC HttpResponseBase 对象,该对象可以通过 MVC 控制器返回。

        要明确回答这个问题,我想您只会对 BuildWebRequest() 函数感兴趣。但是,它演示了如何在整个管道中移动 - 从 BaseRequest > Request 然后 Response > BaseResponse 转换。我认为分享两者会很有用。

        通过这些类,您可以拥有一个充当 Web 代理的 MVC 服务器。

        希望这会有所帮助!

        控制器:

        [HandleError]
        public class MyProxy : AsyncController
        {
            [HttpGet]
            public void RedirectAsync()
            {
                AsyncManager.OutstandingOperations.Increment();
        
                var hubBroker = new RequestBroker();
                hubBroker.BrokerCompleted += (sender, e) =>
                {
                    this.AsyncManager.Parameters["brokered"] = e.Response;
                    this.AsyncManager.OutstandingOperations.Decrement();
                };
        
                hubBroker.BrokerAsync(this.Request, redirectTo);
           }
        
            public ActionResult RedirectCompleted(HttpWebResponse brokered)
            {
                RequestBroker.BuildControllerResponse(this.Response, brokered);
                return new HttpStatusCodeResult(Response.StatusCode);
            }
        }
        

        这是完成繁重工作的代理类:

        namespace MyProxy
        {
            /// <summary>
            /// Asynchronous operation to proxy or "broker" a request via MVC
            /// </summary>
            internal class RequestBroker
            {
                /*
                 * HttpWebRequest is a little protective, and if we do a straight copy of header information we will get ArgumentException for a set of 'restricted' 
                 * headers which either can't be set or need to be set on other interfaces. This is a complete list of restricted headers.
                 */
                private static readonly string[] RestrictedHeaders = new string[] { "Accept", "Connection", "Content-Length", "Content-Type", "Date", "Expect", "Host", "If-Modified-Since", "Range", "Referer", "Transfer-Encoding", "User-Agent", "Proxy-Connection" };
        
                internal class BrokerEventArgs : EventArgs
                {
                    public DateTime StartTime { get; set; }
        
                    public HttpWebResponse Response { get; set; }
                }
        
                public delegate void BrokerEventHandler(object sender, BrokerEventArgs e);
        
                public event BrokerEventHandler BrokerCompleted;
        
                public void BrokerAsync(HttpRequestBase requestToBroker, string redirectToUrl)
                {
                    var httpRequest = BuildWebRequest(requestToBroker, redirectToUrl);
        
                    var brokerTask = new Task(() => this.DoBroker(httpRequest));
                    brokerTask.Start();
                }
        
                private void DoBroker(HttpWebRequest requestToBroker)
                {
                    var startTime = DateTime.UtcNow;
        
                    HttpWebResponse response;
                    try
                    {
                        response = requestToBroker.GetResponse() as HttpWebResponse;
                    }
                    catch (WebException e)
                    {
                        Trace.TraceError("Broker Fail: " + e.ToString());
        
                        response = e.Response as HttpWebResponse;
                    }
        
                    var args = new BrokerEventArgs()
                    {
                        StartTime = startTime,
                        Response = response,
                    };
        
                    this.BrokerCompleted(this, args);
                }
        
                public static void BuildControllerResponse(HttpResponseBase httpResponseBase, HttpWebResponse brokeredResponse)
                {
                    if (brokeredResponse == null)
                    {
                        PerfCounters.ErrorCounter.Increment();
        
                        throw new GriddleException("Failed to broker a response. Refer to logs for details.");
                    }
        
                    httpResponseBase.Charset = brokeredResponse.CharacterSet;
                    httpResponseBase.ContentType = brokeredResponse.ContentType;
        
                    foreach (Cookie cookie in brokeredResponse.Cookies)
                    {
                        httpResponseBase.Cookies.Add(CookieToHttpCookie(cookie));
                    }
        
                    foreach (var header in brokeredResponse.Headers.AllKeys
                        .Where(k => !k.Equals("Transfer-Encoding", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        httpResponseBase.Headers.Add(header, brokeredResponse.Headers[header]);
                    }
        
                    httpResponseBase.StatusCode = (int)brokeredResponse.StatusCode;
                    httpResponseBase.StatusDescription = brokeredResponse.StatusDescription;
        
                    BridgeAndCloseStreams(brokeredResponse.GetResponseStream(), httpResponseBase.OutputStream);
                }
        
                private static HttpWebRequest BuildWebRequest(HttpRequestBase requestToBroker, string redirectToUrl)
                {
                    var httpRequest = (HttpWebRequest)WebRequest.Create(redirectToUrl);
        
                    if (requestToBroker.Headers != null)
                    {
                        foreach (var header in requestToBroker.Headers.AllKeys)
                        {
                            if (RestrictedHeaders.Any(h => header.Equals(h, StringComparison.InvariantCultureIgnoreCase)))
                            {
                                continue;
                            }                   
        
                            httpRequest.Headers.Add(header, requestToBroker.Headers[header]);
                        }
                    }
        
                    httpRequest.Accept = string.Join(",", requestToBroker.AcceptTypes);
                    httpRequest.ContentType = requestToBroker.ContentType;
                    httpRequest.Method = requestToBroker.HttpMethod;
        
                    if (requestToBroker.UrlReferrer != null)
                    {
                        httpRequest.Referer = requestToBroker.UrlReferrer.AbsoluteUri;
                    }
        
                    httpRequest.UserAgent = requestToBroker.UserAgent;
        
                    /* This is a performance change which I like.
                     * If this is not explicitly set to null, the CLR will do a registry hit for each request to use the default proxy.
                     */
                    httpRequest.Proxy = null;
        
                    if (requestToBroker.HttpMethod.Equals("POST", StringComparison.InvariantCultureIgnoreCase))
                    {
                        BridgeAndCloseStreams(requestToBroker.InputStream, httpRequest.GetRequestStream());
                    }
        
                    return httpRequest;
                }
        
                /// <summary>
                /// Convert System.Net.Cookie into System.Web.HttpCookie
                /// </summary>
                private static HttpCookie CookieToHttpCookie(Cookie cookie)
                {
                    HttpCookie httpCookie = new HttpCookie(cookie.Name);
        
                    foreach (string value in cookie.Value.Split('&'))
                    {
                        string[] val = value.Split('=');
                        httpCookie.Values.Add(val[0], val[1]);
                    }
        
                    httpCookie.Domain = cookie.Domain;
                    httpCookie.Expires = cookie.Expires;
                    httpCookie.HttpOnly = cookie.HttpOnly;
                    httpCookie.Path = cookie.Path;
                    httpCookie.Secure = cookie.Secure;
        
                    return httpCookie;
                }
        
                /// <summary>
                /// Reads from stream into the to stream
                /// </summary>
                private static void BridgeAndCloseStreams(Stream from, Stream to)
                {
                    try
                    {
                        int read;
                        do
                        {
                            read = from.ReadByte();
        
                            if (read != -1)
                            {
                                to.WriteByte((byte)read);
                            }
                        }
                        while (read != -1);
                    }
                    finally 
                    {
                        from.Close();
                        to.Close();
                    }
                }
            }
        }
        

        【讨论】:

          【解决方案9】:

          要在 ASP.NET MVC4 .NET 4.5 中获取 HttpRequest,您可以执行以下操作:

          this.HttpContext.ApplicationInstance.Context.Request
          

          【讨论】:

            猜你喜欢
            • 2013-02-22
            • 2020-08-05
            • 2013-03-21
            • 1970-01-01
            • 1970-01-01
            • 2013-04-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多