¿Cómo convierto una HttpRequestBase en un objeto HttpRequest?


Respuestas:


50

¿Es su método, por lo que puede volver a escribirlo para tomarlo HttpRequestBase? Si no, siempre se puede obtener la corriente HttpRequestde HttpContext.Current.HttpRequesttransmitir. Sin embargo, a menudo envuelvo el acceso a HttpContext dentro de una clase como se menciona en ASP.NET: Eliminación de las dependencias de System.Web para una mejor compatibilidad con las pruebas unitarias.


4
Vergonzosamente, también pensé en esto y no funciona. El HttpContext es el contexto MVC ... por lo que no hay una propiedad 'Actual' expuesta en él. No estoy seguro de cómo obtener acceso a HttpContext.Current 'oldschool' ... ???
Pure.Krome

48
Para asegurarse de que está tomando la clase HttpContext en lugar del miembro controlador, intente usar System.Web.HttpContext.Current.
Kevin Hakanson

1
Necesitaba usar el espacio de nombres completo porque estaba tomando la propiedad actual del espacio de nombres MVC. salud. Nota para los demás: no hagas lo que estoy haciendo. es un VeryBadThing (tm).
Pure.Krome

Link está muerto; El dominio developmentmadness.com expiró, la página de relleno de GoDaddy ahora
Chris Moschini

2
System.Web.HttpContext.Current.Request
Jenny O'Reilly

72

Siempre debe usar HttpRequestBase y HttpResponseBase en su aplicación a diferencia de las versiones concretas que son imposibles de probar (sin typemock o alguna otra magia).

Simplemente use la clase HttpRequestWrapper para convertir como se muestra a continuación.

var httpRequestBase = new HttpRequestWrapper(Context.Request);

2
Otra nota que, no solo usa HttpRequestBasey HttpResponseBase, también HttpContextBase. :)
Junle Li

30

Puedes usar

System.Web.HttpContext.Current.Request

La clave aquí es que necesita el espacio de nombres completo para llegar al HttpContext "correcto".

Sé que han pasado 4 años desde que se hizo esta pregunta, pero si esto ayudará a alguien, ¡aquí tiene!

(Editar: Veo que Kevin Hakanson ya dio esta respuesta ... así que espero que mi respuesta ayude a aquellas personas que solo leen respuestas y no comentarios) :)


9

Intente usar / crear un HttpRequestWrapper usando su HttpRequestBase.


8

Para obtener HttpRequest en ASP.NET MVC4 .NET 4.5, puede hacer lo siguiente:

this.HttpContext.ApplicationInstance.Context.Request

4

Normalmente, cuando necesita acceder a la HttpContextpropiedad en una acción de controlador, hay algo que puede hacer mejor en cuanto al diseño.

Por ejemplo, si necesita acceder al usuario actual, asigne a su método de acción un parámetro de tipo IPrincipal, que debe completar con Attributey simular como desee al realizar la prueba. Para ver un pequeño ejemplo de cómo, consulte esta publicación de blog , y específicamente el punto 7.


¡Totalmente de acuerdo! El problema es que no puedo modificar la biblioteca de clases actual que debemos usar ... así que esto no me ayuda mucho :(
Pure.Krome

2

No hay forma de convertir entre estos tipos.

Tuvimos un caso similar. Reescribimos nuestros métodos de clases / servicios web para que usen HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... en lugar de los tipos de nombre de cierre sin el sufijo "Base" (HttpContext, ... HttpSessionState). Son mucho más fáciles de manejar con burlas caseras.

Siento que no pudieras hacerlo.


1
No es cierto.var httpRequest = Context.Request; var httpRequestBase = new HttpRequestWrapper (Context.Request);
CountZero

2

Este es un ASP.Net MVC 3.0 AsyncController que acepta solicitudes, convierte el objeto HttpRequestBase MVC entrante en un System.Web.HttpWebRequest. Luego envía la solicitud de forma asincrónica. Cuando la respuesta regresa, vuelve a convertir System.Web.HttpWebResponse en un objeto MVC HttpResponseBase que se puede devolver a través del controlador MVC.

Para responder esta pregunta explícitamente, supongo que solo estaría interesado en la función BuildWebRequest (). Sin embargo, demuestra cómo moverse a través de toda la canalización: conversión de BaseRequest> Solicitud y luego Respuesta> BaseResponse. Pensé que compartir ambos sería útil.

A través de estas clases, puede tener un servidor MVC que actúa como proxy web.

¡Espero que esto ayude!

Controlador:

[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);
    }
}

Esta es la clase de proxy que hace el trabajo pesado:

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

1

Funcionó como dijo Kevin.

Estoy usando un método estático para recuperar el HttpContext.Current.Request, por lo que siempre tengo un HttpRequestobjeto para usar cuando sea necesario.

Ayudante aquí en clase

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

Aquí en Controller

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

Aquí en vista

bool bUserLogado = ProjectNamespace.Models.AcessoModel.UsuarioLogado(
                      ProjectNamespace.Models.Helper.GetRequest()
                   );

if (bUserLogado == false) { Response.Redirect("/"); }

Mi Método UsuarioLogado

public static bool UsuarioLogado(HttpRequest Request)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.