Come si converte un HttpRequestBase in un oggetto HttpRequest?


Risposte:


50

È il tuo metodo, quindi puoi riscriverlo per prenderlo HttpRequestBase? In caso contrario, puoi sempre ottenere la corrente HttpRequestda HttpContext.Current.HttpRequesttrasmettere. Tuttavia, spesso inserisco l'accesso a HttpContext all'interno di una classe come menzionata in ASP.NET: Rimozione delle dipendenze System.Web per un migliore supporto per i test di unità.


4
In modo imbarazzante, ho pensato anche a questo e non funziona. HttpContext è il contesto MVC .. quindi non è esposta alcuna proprietà "Current". Non sono sicuro di come accedere a "oldschool" HttpContext.Current ... ???
Pure.Krome,

48
Per essere sicuro di prendere la classe HttpContext invece del membro del controller, prova a usare System.Web.HttpContext.Current.
Kevin Hakanson,

1
Avevo bisogno di utilizzare lo spazio dei nomi completo perché stava prendendo la proprietà dello spazio dei nomi MVC corrente. Saluti. Nota per gli altri: non fare quello che sto facendo. è un VeryBadThing (tm).
Pure.Krome,

Link è morto; Dominio developmentalmadness.com scaduto, pagina di riempimento GoDaddy ora
Chris Moschini

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

72

Dovresti sempre usare HttpRequestBase e HttpResponseBase nella tua applicazione al contrario delle versioni concrete che sono impossibili da testare (senza typemock o qualche altra magia).

Usa semplicemente la classe HttpRequestWrapper per convertire come mostrato di seguito.

var httpRequestBase = new HttpRequestWrapper(Context.Request);

2
Un'altra nota che, non solo uso HttpRequestBasee HttpResponseBase, anche HttpContextBase. :)
Junle Li

30

Puoi semplicemente usare

System.Web.HttpContext.Current.Request

La chiave qui è che hai bisogno dello spazio dei nomi completo per ottenere il "corretto" HttpContext.

So che sono passati 4 anni da quando è stata posta questa domanda, ma se questo aiuterà qualcuno, allora eccoti!

(Modifica: vedo che Kevin Hakanson ha già dato questa risposta ... quindi spero che la mia risposta aiuti quelle persone che leggono solo risposte e non commenti.) :)


9

Prova a usare / creare un HttpRequestWrapper usando il tuo HttpRequestBase.


8

Per ottenere HttpRequest in ASP.NET MVC4 .NET 4.5, puoi eseguire le operazioni seguenti:

this.HttpContext.ApplicationInstance.Context.Request

4

In genere, quando è necessario accedere alla HttpContextproprietà in un'azione del controller, è possibile eseguire operazioni migliori in termini di progettazione.

Ad esempio, se hai bisogno di accedere all'utente corrente, dai al tuo metodo di azione un parametro di tipo IPrincipal, che inserisci con Attributee simula come desideri durante il test. Per un piccolo esempio su come, vedere questo post del blog e in particolare il punto 7.


Totalmente d'accordo! il problema è che non posso modificare l'attuale libreria di classi che dobbiamo usare .. quindi questo non mi aiuta molto :(
Pure.Krome,

2

Non c'è modo di convertire tra questi tipi.

Abbiamo avuto un caso simile. Abbiamo riscritto i nostri metodi di classi / servizi Web in modo che utilizzino HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... invece dei tipi di nome di chiusura senza il suffisso "Base" (HttpContext, ... HttpSessionState). Sono molto più facili da gestire con le prese in giro fatte in casa.

Mi dispiace che tu non l'abbia fatto.


1
Non true.var httpRequest = Context.Request; var httpRequestBase = new HttpRequestWrapper (Context.Request);
CountZero

2

Questo è un ASP.Net MVC 3.0 AsyncController che accetta le richieste, converte l'oggetto HttpRequestBase MVC in ingresso in un System.Web.HttpWebRequest. Quindi invia la richiesta in modo asincrono. Quando la risposta ritorna, converte di nuovo System.Web.HttpWebResponse in un oggetto MVC HttpResponseBase che può essere restituito tramite il controller MVC.

Per rispondere a questa domanda in modo esplicito, immagino che ti interesserebbe solo la funzione BuildWebRequest (). Tuttavia, dimostra come spostarsi attraverso l'intera pipeline, convertendo da BaseRequest> Request e quindi Response> BaseResponse. Ho pensato che condividere entrambi sarebbe stato utile.

Attraverso queste classi, puoi avere un server MVC che funge da proxy web.

Spero che sia di aiuto!

Controller:

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

Questa è la classe proxy che fa il lavoro pesante:

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

Ha funzionato come ha detto Kevin.

Sto usando un metodo statico per recuperare il file HttpContext.Current.Request, quindi ho sempre un HttpRequestoggetto da usare quando necessario.

Qui in classe Helper

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

Qui in Controller

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

Qui in vista

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

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

Il mio metodo UsuarioLogado

public static bool UsuarioLogado(HttpRequest Request)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.