Jak przekonwertować HttpRequestBase na obiekt HttpRequest?


Odpowiedzi:


50

Czy to twoja metoda, więc możesz ją ponownie napisać HttpRequestBase? Jeśli nie, zawsze możesz przekazać prąd HttpRequestz HttpContext.Current.HttpRequest. Jednak często zawijam dostęp do HttpContext wewnątrz klasy, jak wspomniano w ASP.NET: Usuwanie zależności System.Web w celu lepszej obsługi testów jednostkowych.


4
Żenująco, ja też o tym pomyślałem i to nie działa. HttpContext jest kontekstem MVC, więc nie ma w nim żadnej właściwości „Current”. Nie jestem pewien, jak uzyskać dostęp do „oldschool” HttpContext.Current ... ???
Pure.Krome,

48
Aby upewnić się, że pobierasz klasę HttpContext zamiast elementu członkowskiego kontrolera, spróbuj użyć System.Web.HttpContext.Current.
Kevin Hakanson

1
Musiałem użyć pełnej przestrzeni nazw, ponieważ pobierała bieżącą właściwość przestrzeni nazw MVC. Twoje zdrowie. Uwaga dla innych: nie rób tego, co ja. to jest VeryBadThing (tm).
Pure.Krome

Link nie żyje; developmentalmadness.com domena wygasła, strona wypełniacz GoDaddy teraz
Chris Moschini

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

72

Powinieneś zawsze używać HttpRequestBase i HttpResponseBase w swojej aplikacji w przeciwieństwie do wersji konkretnych, których nie można przetestować (bez blokowania typu lub innej magii).

Po prostu użyj klasy HttpRequestWrapper, aby przekonwertować, jak pokazano poniżej.

var httpRequestBase = new HttpRequestWrapper(Context.Request);

2
Inna uwaga, że nie należy używać HttpRequestBase, a HttpResponseBasetakże HttpContextBase. :)
Junle Li

30

Możesz po prostu użyć

System.Web.HttpContext.Current.Request

Kluczem jest to, że aby dostać się do „prawidłowego” HttpContext, potrzebujesz pełnej przestrzeni nazw.

Wiem, że minęły 4 lata, odkąd zadano to pytanie, ale jeśli to komuś pomoże, to proszę bardzo!

(Edycja: Widzę, że Kevin Hakanson już udzielił tej odpowiedzi ... więc mam nadzieję, że moja odpowiedź pomoże tym, którzy po prostu czytają odpowiedzi, a nie komentarze.) :)


9

Spróbuj użyć / utworzyć HttpRequestWrapper przy użyciu HttpRequestBase.


8

Aby uzyskać HttpRequest w ASP.NET MVC4 .NET 4.5, możesz wykonać następujące czynności:

this.HttpContext.ApplicationInstance.Context.Request

4

Zwykle, gdy potrzebujesz uzyskać dostęp do HttpContextwłaściwości w akcji kontrolera, jest coś, co możesz zrobić lepiej, mądrze zaprojektować.

Na przykład, jeśli chcesz uzyskać dostęp do bieżącego użytkownika, nadaj swojej metodzie akcji parametr typu IPrincipal, który Attributepodczas testowania wypełniasz znakiem i mock, jak chcesz. Mały przykład, jak to zrobić , znajduje się w tym poście na blogu , a konkretnie w punkcie 7.


Całkowicie zgodził! Problem polega na tym, że nie mogę zmodyfikować bieżącej biblioteki klas, z której mamy korzystać ... więc to mi nie pomaga :(
Pure.Krome

2

Nie ma możliwości konwersji między tymi typami.

Mieliśmy podobny przypadek. Przepisaliśmy nasze metody klas / usług internetowych, aby używały HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... zamiast typów nazw bliskich bez przyrostka „Base” (HttpContext, ... HttpSessionState). Są o wiele łatwiejsze w obsłudze dzięki domowej roboty kpinie.

Przykro mi, że nie mogłeś tego zrobić.


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

2

To jest ASP.Net MVC 3.0 AsyncController, który akceptuje żądania, konwertuje przychodzący obiekt HttpRequestBase MVC na System.Web.HttpWebRequest. Następnie wysyła żądanie asynchronicznie. Gdy odpowiedź wróci, konwertuje System.Web.HttpWebResponse z powrotem na obiekt MVC HttpResponseBase, który może zostać zwrócony przez kontroler MVC.

Aby jednoznacznie odpowiedzieć na to pytanie, myślę, że interesuje Cię tylko funkcja BuildWebRequest (). Pokazuje jednak, jak przejść przez cały potok - konwersję z BaseRequest> Request, a następnie Response> BaseResponse. Pomyślałem, że przydałoby się udostępnienie obu.

Dzięki tym klasom możesz mieć serwer MVC, który działa jako internetowy serwer proxy.

Mam nadzieję że to pomoże!

Kontroler:

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

To jest klasa proxy, która wykonuje ciężkie prace:

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

Zadziałało tak, jak powiedział Kevin.

Używam metody statycznej do pobierania HttpContext.Current.Request, więc zawsze mam HttpRequestobiekt do użycia w razie potrzeby.

Tutaj w pomocniku klasy

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

Tutaj w kontrolerze

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

Tutaj w widoku

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

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

Moja metoda UsuarioLogado

public static bool UsuarioLogado(HttpRequest Request)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.