Bir HttpRequestBase'i HttpRequest nesnesine nasıl dönüştürebilirim?


Yanıtlar:


50

Yöntemin mi, yani tekrar yazmak için HttpRequestBasemi? Değilse, her zaman akımı elde edebilirsiniz HttpRequestdan HttpContext.Current.HttpRequestaktarmak. Ancak, daha iyi birim testi desteği için ASP.NET: System.Web Bağımlılıklarını Kaldırma'da belirtildiği gibi bir sınıf içinde HttpContext'e erişimi sık sık sarıyorum .


4
Utanç verici bir şekilde, bunu da düşündüm ve işe yaramıyor. HttpContext, MVC bağlamıdır .. bu nedenle, üzerinde 'Current' özelliği gösterilmez. 'Oldschool' HttpContext.Current'e nasıl erişeceğimi bilmiyorum ... ???
Pure.Krome

48
Denetleyici üyesi yerine HttpContext sınıfını aldığınızdan emin olmak için, System.Web.HttpContext.Current.
Kevin Hakanson

1
Geçerli MVC ad alanı özelliğini aldığı için tam ad alanını kullanmam gerekiyordu. şerefe. Başkalarına not: Yaptığım şeyi yapma. bu bir VeryBadThing (tm).
Pure.Krome

Bağlantı öldü; developmentalmadness.com etki alanının süresi doldu, GoDaddy doldurucu sayfası şimdi
Chris Moschini

2
System.Web.HttpContext.Current.Request
Krisztián Balla

72

Test edilmesi imkansız olan (typemock veya başka bir sihir olmadan) somut sürümlerin aksine, uygulamanızda her zaman HttpRequestBase ve HttpResponseBase'i kullanmalısınız.

Aşağıda gösterildiği gibi dönüştürmek için yalnızca HttpRequestWrapper sınıfını kullanın.

var httpRequestBase = new HttpRequestWrapper(Context.Request);

3
Sadece kullanmak başka not HttpRequestBaseve HttpResponseBaseayrıca, HttpContextBase. :)
Junle Li

Bu yanlış yöne çeviriyor. Soru şuydu: Ben eğer varsa bir HttpRequestBase, nasıl yok olsun gerçek HttpRequestondan?
Suncat2000

30

Sadece kullanabilirsin

System.Web.HttpContext.Current.Request

Buradaki anahtar, "doğru" HttpContext'e ulaşmak için tam ad alanına ihtiyacınız olmasıdır.

Bu sorunun sorulmasının üzerinden 4 yıl geçtiğini biliyorum, ama bu birisine yardımcı olacaksa, o zaman buyrun!

(Düzenleme: Kevin Hakanson'un bu cevabı zaten verdiğini görüyorum ... bu yüzden umarım cevabım yorumları değil, sadece cevapları okuyanlara yardımcı olur.) :)


9

HttpRequestBase'inizi kullanarak bir HttpRequestWrapper kullanmayı / oluşturmayı deneyin.


9

ASP.NET MVC4 .NET 4.5'te HttpRequest almak için aşağıdakileri yapabilirsiniz:

this.HttpContext.ApplicationInstance.Context.Request

4

Tipik olarak HttpContext, bir denetleyici eyleminde özelliğe erişmeniz gerektiğinde , tasarım açısından daha iyi yapabileceğiniz bir şey vardır.

Örneğin, geçerli kullanıcıya erişmeniz gerekiyorsa, eylem yönteminize test sırasında istediğiniz gibi IPrincipalbir Attributeve alay ile dolduracağınız bir tür parametresi verin . Nasıl yapılacağına dair küçük bir örnek için bu blog gönderisine bakın ve özellikle 7. noktaya bakın.


Tamamen kabul edildi! sorun şu ki, kullanmamız gereken mevcut sınıf kitaplığını değiştiremiyorum .. bu yüzden bu bana pek yardımcı olmuyor :(
Pure.Krome

2

Bu türler arasında dönüştürme yapmanın bir yolu yoktur.

Benzer bir davamız vardı. Sınıfları / web hizmetleri yöntemlerimizi, "Base" soneki (HttpContext, ... HttpSessionState) olmayan close name türleri yerine HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... kullanacak şekilde yeniden yazdık. Ev yapımı alaylarla başa çıkmak çok daha kolaydır.

Yapamadığın için üzgünüm.


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

2

Bu, istekleri kabul eden, gelen HttpRequestBase MVC nesnesini System.Web.HttpWebRequest'e dönüştüren bir ASP.Net MVC 3.0 AsyncController'dır. Daha sonra isteği eşzamansız olarak gönderir. Yanıt geri geldiğinde, System.Web.HttpWebResponse'yi, MVC denetleyicisi aracılığıyla döndürülebilen bir MVC HttpResponseBase nesnesine dönüştürür.

Bu soruyu açıkça yanıtlamak için, sanırım yalnızca BuildWebRequest () işleviyle ilgileniyorsunuz. Bununla birlikte, tüm ardışık düzen boyunca nasıl hareket edileceğini gösterir - BaseRequest> Request ve ardından Response> BaseResponse'den dönüştürme. İkisini de paylaşmanın yararlı olacağını düşündüm.

Bu sınıflar aracılığıyla, bir web proxy'si görevi gören bir MVC sunucunuz olabilir.

Bu yardımcı olur umarım!

Denetleyici:

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

Bu, ağır işi yapan proxy sınıfıdır:

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

Kevin'in dediği gibi çalıştı.

Geri almak için statik bir yöntem kullanıyorum HttpContext.Current.Requestve bu nedenle HttpRequestgerektiğinde kullanmak için her zaman bir nesneye sahibim .

Sınıf Yardımcısı'nda

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

Kontrolörde

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

Burada Görünümde

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

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

Metodum UsuarioLogado

public static bool UsuarioLogado(HttpRequest Request)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.