代码之家  ›  专栏  ›  技术社区  ›  Pure.Krome

如何将httpRequestBase转换为httpRequest对象?

  •  77
  • Pure.Krome  · 技术社区  · 15 年前

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

    不管怎样,我能转换这个吗?

    我能/应该做什么??

    9 回复  |  直到 8 年前
        1
  •  44
  •   Kevin Hakanson    15 年前

    这是你的方法吗,所以你可以重写它 HttpRequestBase ?如果没有,你总是可以得到电流 HttpRequest HttpContext.Current.HttpRequest 传下去。但是,我经常将对httpContext的访问包装在类中,如中所述 ASP.NET: Removing System.Web Dependencies 以获得更好的单元测试支持。

        2
  •  61
  •   Jon Schneider Stefan    8 年前

    您应该在应用程序中始终使用httpRequestBase和httpResponseBase,作为不可能测试的具体版本的附件(没有typemock或其他一些魔力)。

    只需使用 HttpRequestWrapper 要转换的类,如下所示。

    var httpRequestBase = new HttpRequestWrapper(Context.Request);
    
        3
  •  26
  •   adamgede    11 年前

    你可以用

    System.Web.HttpContext.Current.Request
    

    这里的关键是您需要完整的名称空间才能到达“正确的”httpContext。

    我知道这个问题已经问了4年了,但如果这能帮助别人,那就给你!

    (编辑:我看到凯文·哈坎森已经给出了这个答案……所以希望我的回答能帮助那些只看答案而不看评论的人。):)

        4
  •  9
  •   Klaas    14 年前

    尝试使用httpRequestBase使用/创建httpRequestWrapper。

        5
  •  7
  •   Mohamed Mansour    10 年前

    要获取ASP.NET MVC4.NET 4.5中的httpRequest,可以执行以下操作:

    this.HttpContext.ApplicationInstance.Context.Request
    
        6
  •  4
  •   Tomas Aschan    15 年前

    通常当您需要访问 HttpContext 属性在控制器操作中,您可以做一些更好的设计。

    例如,如果需要访问当前用户,请为操作方法提供一个类型为的参数 IPrincipal ,用 Attribute 在测试时,你可以随意模仿。有关如何操作的小示例,请参见 this blog post 特别是第7点。

        7
  •  2
  •   Barbara Post    14 年前

    无法在这些类型之间转换。

    我们也有类似的病例。我们重写了类/Web服务方法,以便它们使用httpContextBase、httpApplicationStateBase、httpServerUtilityBase、httpSessionStateBase…而不是没有“base”后缀的关闭名称类型(httpContext,…httpsessionstate)。他们更容易处理自制的模仿。

    我很抱歉你做不到。

        8
  •  2
  •   Kenn Zelleriation    11 年前

    这是一个ASP.NET MVC 3.0 AsyncController,它接受请求,将入站httpRequestBase MVC对象转换为System.Web.httpWebRequest。然后它异步发送请求。当响应返回时,它将System.Web.httpWebResponse转换回可通过MVC控制器返回的MVC httpResponseBase对象。

    要明确回答这个问题,我想您只对buildWebRequest()函数感兴趣。但是,它演示了如何在整个管道中移动—从baserequest转换为request,然后再转换为response。我认为分享两者都是有用的。

    通过这些类,您可以拥有一个充当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
  •  1
  •   RogerGales    13 年前

    就像凯文说的那样。

    我正在使用静态方法来检索 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("/"); }
    

    我的方法通常是

    public static bool UsuarioLogado(HttpRequest Request)