Làm cách nào để chuyển đổi HttpRequestBase thành đối tượng HttpRequest?


87

bên trong bộ điều khiển ASP.NET MVC của tôi, tôi có một phương thức yêu cầu một HttpRequestđối tượng. Tất cả những gì tôi có quyền truy cập là một HttpRequestBaseđối tượng.

Có anyway tôi có thể chuyển đổi điều này bằng cách nào đó?

Tôi có thể / nên làm gì ??


4
Lưu ý: Câu hỏi 'ngược lại' với câu hỏi này là ở đây stackoverflow.com/questions/15275370/…
Simon_Weaver,

Câu trả lời:


50

Đó có phải là phương pháp của bạn, vì vậy bạn có thể viết lại nó để thực hiện HttpRequestBase? Nếu không, bạn luôn có thể nhận được dòng điện HttpRequesttừ đó HttpContext.Current.HttpRequestđi qua. Tuy nhiên, tôi thường bọc quyền truy cập vào HttpContext bên trong một lớp như đã đề cập trong ASP.NET: Loại bỏ Phụ thuộc System.Web để hỗ trợ kiểm thử đơn vị tốt hơn.


4
Thật đáng kinh ngạc, tôi cũng đã nghĩ đến điều này và nó không hoạt động. HttpContext là ngữ cảnh MVC .. vì vậy không có thuộc tính 'Hiện tại' được hiển thị trên đó. Tôi không chắc làm thế nào để truy cập vào 'oldschool' HttpContext.Current ... ???
Pure.Krome 21/09/09

48
Để chắc chắn rằng bạn đang lấy lớp HttpContext thay vì thành viên bộ điều khiển, hãy thử và sử dụng System.Web.HttpContext.Current.
Kevin Hakanson 21/09/09

1
Tôi cần sử dụng không gian tên đầy đủ vì nó đang sử dụng thuộc tính không gian tên MVC hiện tại. hoan hô. Lưu ý với những người khác: đừng làm những gì tôi đang làm. đó là VeryBadThing (tm).
Pure.Krome 21/09/09

Liên kết đã chết; developmentalmadness.com miền hết hạn, GoDaddy trang phụ hiện nay
Chris Moschini

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

72

Bạn nên luôn sử dụng HttpRequestBase và HttpResponseBase trong ứng dụng của mình thay vì các phiên bản cụ thể không thể kiểm tra được (không có chính tả hoặc một số phép thuật khác).

Đơn giản chỉ cần sử dụng lớp HttpRequestWrapper để chuyển đổi như hình dưới đây.

var httpRequestBase = new HttpRequestWrapper(Context.Request);

2
Một lưu ý khác rằng, không chỉ sử dụng HttpRequestBaseHttpResponseBase, còn HttpContextBase. :)
Junle Li

30

Bạn chỉ có thể sử dụng

System.Web.HttpContext.Current.Request

Chìa khóa ở đây là bạn cần không gian tên đầy đủ để truy cập HttpContext "đúng".

Tôi biết đã 4 năm kể từ khi câu hỏi này được hỏi, nhưng nếu điều này sẽ giúp ích cho ai đó, thì bạn xem đây!

(Chỉnh sửa: Tôi thấy rằng Kevin Hakanson đã đưa ra câu trả lời này ... vì vậy hy vọng phản hồi của tôi sẽ giúp những người chỉ đọc câu trả lời chứ không phải bình luận.) :)


9

Cố gắng sử dụng / tạo HttpRequestWrapper bằng HttpRequestBase của bạn.


8

Để tải HttpRequest trong ASP.NET MVC4 .NET 4.5, bạn có thể làm như sau:

this.HttpContext.ApplicationInstance.Context.Request

4

Thông thường, khi bạn cần truy cập thuộc HttpContexttính trong một hành động của bộ điều khiển, bạn có thể làm tốt hơn khi thiết kế.

Ví dụ: nếu bạn cần truy cập người dùng hiện tại, hãy cung cấp cho phương thức hành động của bạn một tham số kiểu IPrincipal, mà bạn điền với một Attributevà mô hình như bạn muốn khi thử nghiệm. Để biết một ví dụ nhỏ về cách thực hiện, hãy xem bài đăng trên blog này và cụ thể là điểm 7.


Hoàn toàn đồng ý! Vấn đề là, tôi không thể sửa đổi các thư viện lớp hiện tại chúng tôi buộc phải sử dụng .. vì vậy đây không giúp tôi nhiều :(
Pure.Krome

2

Không có cách nào để chuyển đổi giữa các loại này.

Chúng tôi đã có một trường hợp tương tự. Chúng tôi đã viết lại các phương thức lớp / dịch vụ web của mình để chúng sử dụng HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... thay vì các loại tên gần gũi không có hậu tố "Cơ sở" (HttpContext, ... HttpSessionState). Chúng dễ dàng xử lý hơn rất nhiều với chế độ chế tạo tại nhà.

Tôi cảm thấy tiếc vì bạn đã không thể làm điều đó.


1
Không đúng.var httpRequest = Context.Request; var httpRequestBase = new HttpRequestWrapper (Context.Request);
CountZero

2

Đây là ASP.Net MVC 3.0 AsyncController chấp nhận yêu cầu, chuyển đổi đối tượng HttpRequestBase MVC gửi đến thành System.Web.HttpWebRequest. Sau đó, nó sẽ gửi yêu cầu không đồng bộ. Khi phản hồi quay trở lại, nó sẽ chuyển đổi System.Web.HttpWebResponse trở lại thành một đối tượng MVC HttpResponseBase có thể được trả về thông qua bộ điều khiển MVC.

Để trả lời câu hỏi này một cách rõ ràng, tôi đoán bạn chỉ quan tâm đến hàm BuildWebRequest (). Tuy nhiên, nó thể hiện cách di chuyển qua toàn bộ đường ống - chuyển đổi từ BaseRequest> Request và sau đó là Response> BaseResponse. Tôi nghĩ rằng chia sẻ cả hai sẽ hữu ích.

Thông qua các lớp này, bạn có thể có một máy chủ MVC hoạt động như một proxy web.

Hi vọng điêu nay co ich!

Bộ điều khiển:

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

Đây là lớp proxy thực hiện công việc nặng nhọc:

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

Nó đã hoạt động như Kevin nói.

Tôi đang sử dụng một phương thức tĩnh để truy xuất HttpContext.Current.Requestvà vì vậy luôn có một HttpRequestđối tượng để sử dụng khi cần thiết.

Đây trong Trình trợ giúp lớp học

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

Đây trong Bộ điều khiển

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

Đây trong Xem

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

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

Phương pháp của tôi UsuarioLogado

public static bool UsuarioLogado(HttpRequest Request)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.