在ASP.NET MVC控制器内部,我有一个需要HttpRequest对象的方法。我只能访问的是一个HttpRequestBase对象。
无论如何,我可以通过某种方式进行转换吗?
我能/应该做什么?
在ASP.NET MVC控制器内部,我有一个需要HttpRequest对象的方法。我只能访问的是一个HttpRequestBase对象。
无论如何,我可以通过某种方式进行转换吗?
我能/应该做什么?
Answers:
是您的方法,因此您可以重新编写它以使用HttpRequestBase?如果没有,你总是可以得到当前HttpRequest的HttpContext.Current.HttpRequest转嫁。但是,我经常将对HttpContext的访问包装在ASP.NET中提到的类中:删除System.Web依赖关系以获得更好的单元测试支持。
您应该始终在应用程序中使用HttpRequestBase和HttpResponseBase,而不是无法测试的具体版本(没有typemock或其他魔术)。
只需使用HttpRequestWrapper类进行转换,如下所示。
var httpRequestBase = new HttpRequestWrapper(Context.Request);
    HttpRequestBaseand HttpResponseBase,而且还要HttpContextBase。:)
                    要在ASP.NET MVC4 .NET 4.5中获取HttpRequest,可以执行以下操作:
this.HttpContext.ApplicationInstance.Context.Request
    通常,当您需要HttpContext在控制器操作中访问属性时,可以做一些更好的明智设计。
例如,如果您需要访问当前用户,请为您的操作方法提供一个类型为的参数,并在测试时根据需要IPrincipal使用Attribute和填充该参数。有关此操作的小示例,请参阅此博客文章,特别是第7点。
无法在这些类型之间进行转换。
我们有一个类似的案例。我们重写了类/ Web服务方法,以便它们使用HttpContextBase,HttpApplicationStateBase,HttpServerUtilityBase,HttpSessionStateBase ...而不是没有“ Base”后缀的关闭名称类型(HttpContext,... HttpSessionState)。使用自制的模拟,它们要容易得多。
对不起,您不能这样做。
这是一个ASP.Net MVC 3.0 AsyncController,它接受请求,将入站HttpRequestBase MVC对象转换为System.Web.HttpWebRequest。然后,它异步发送请求。当响应返回时,它将System.Web.HttpWebResponse转换回MVC HttpResponseBase对象,该对象可以通过MVC控制器返回。
为了明确回答这个问题,我想您只会对BuildWebRequest()函数感兴趣。但是,它演示了如何遍历整个管道-从BaseRequest> Request然后是Response> BaseResponse转换。我认为共享两者将很有用。
通过这些类,您可以拥有充当Web代理的MVC服务器。
希望这可以帮助!
控制器:
[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);
    }
}
这是完成繁重工作的代理类:
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();
            }
        }
    }
}
    就像凯文所说的那样。
我正在使用静态方法来检索HttpContext.Current.Request,因此HttpRequest在需要时总是有一个要使用的对象。
public static HttpRequest GetRequest()
{
    return HttpContext.Current.Request;
}
if (AcessoModel.UsuarioLogado(Helper.GetRequest()))
bool bUserLogado = ProjectNamespace.Models.AcessoModel.UsuarioLogado(
                      ProjectNamespace.Models.Helper.GetRequest()
                   );
if (bUserLogado == false) { Response.Redirect("/"); }
public static bool UsuarioLogado(HttpRequest Request)