Comment convertir une HttpRequestBase en un objet HttpRequest?

à l'intérieur de mon ASP.NET contrôleur MVC, j'ai une méthode qui nécessite un objet HttpRequest . Je n'ai accès qu'à un objet HttpRequestBase .

y a-t-il quelque chose que je puisse convertir?

Que puis-je / dois-je faire??

76
demandé sur Pure.Krome 2009-09-21 05:28:47

9 réponses

est-ce votre méthode, donc vous pouvez réécrire pour prendre HttpRequestBase ? Si non, vous pouvez toujours obtenir le courant HttpRequest de HttpContext.Current.HttpRequest à transmettre. Cependant, j'enroule souvent l'accès au HttpContext dans une classe comme celle mentionnée dans ASP.NET: suppression du système.Dépendances Web pour un meilleur support de test de l'unité.

44
répondu Kevin Hakanson 2009-09-21 01:54:45

vous devez toujours utiliser HttpRequestBase et HttpResponseBase dans votre application, en comparaison avec les versions concrètes qui sont impossibles à tester (sans typographie ou autre magie).

utilisez simplement la classe HttpRequestWrapper pour convertir comme indiqué ci-dessous.

var httpRequestBase = new HttpRequestWrapper(Context.Request);
55
répondu CountZero 2016-12-19 16:28:31

vous pouvez simplement utiliser

System.Web.HttpContext.Current.Request

la clé ici est que vous avez besoin de l'espace de noms complet pour accéder au" correct " HttpContext.

je sais que cela fait 4 ans que cette question a été posée, mais si cela peut aider quelqu'un, Alors voilà!

(Edit: je vois que Kevin Hakanson déjà donné cette réponse...alors j'espère que ma réponse va aider ces gens qui viens de lire les réponses et les commentaires.):)

25
répondu adamgede 2013-06-08 22:47:39

essayez d'utiliser/créer un pirate HttpRequest en utilisant votre base HttpRequest.

9
répondu Klaas 2010-04-18 17:32:03

pour obtenir HttpRequest en ASP.NET MVC4 .net 4.5, vous pouvez faire ce qui suit:

this.HttpContext.ApplicationInstance.Context.Request
7
répondu Mohamed Mansour 2014-03-05 16:40:18

typiquement quand vous avez besoin d'accéder à la propriété HttpContext dans une action de contrôleur, il y a quelque chose que vous pouvez faire de mieux en termes de conception.

par exemple, si vous avez besoin d'accéder à l'utilisateur courant, donnez à votre méthode d'action un paramètre de type IPrincipal , que vous peuplez avec un Attribute et mock comme vous le souhaitez lors des tests. Pour un petit exemple sur comment, voir ce billet de blog , et plus précisément le point 7.

4
répondu Tomas Lycken 2009-09-21 01:37:27

il n'y a aucun moyen de convertir entre ces types.

Nous avons eu un cas similaire. Nous avons réécrit nos méthodes de classes/services web afin qu'elles utilisent HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase... au lieu des types de nom de fermeture sans le suffixe "Base" (HttpContext, ... HttpSessionState). Ils sont beaucoup plus faciles à manipuler avec des moqueries faites maison.

je suis désolé que vous n'ayez pas pu le faire.

2
répondu Barbara Post 2010-09-08 10:18:41

C'est un ASP.Net MVC 3.0 AsyncController qui accepte les requêtes, convertit L'objet MVC entrant HttpRequestBase en un système.Web.HttpWebRequest. Il envoie ensuite la demande de manière asynchrone. Quand la réponse revient, il convertit le système.Web.HttpWebResponse de nouveau dans un objet MVC HttpResponseBase qui peut être retourné via le contrôleur MVC.

pour répondre explicitement à cette question, je suppose que vous ne seriez intéressé que par la fonction BuildWebRequest (). Cependant, il montre comment se déplacer dans l'ensemble du pipeline - conversion de BaseRequest > Request puis Response > BaseResponse. Je pensais que partager les deux serait utile.

grâce à ces classes, vous pouvez avoir un serveur MVC qui agit comme un proxy web.

Espérons que cette aide!

contrôleur:

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

il s'agit de la classe par procuration qui fait la plus lourde levage:

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();
            }
        }
    }
}
2
répondu Kenn 2013-07-26 08:07:49

ça a marché comme Kevin l'a dit.

j'utilise une méthode statique pour récupérer le HttpContext.Current.Request , et j'ai donc toujours un objet HttpRequest à utiliser en cas de besoin.

ici en aide de classe

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

ici dans Controller

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

Ici

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

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

Ma Méthode UsuarioLogado

public static bool UsuarioLogado(HttpRequest Request)
1
répondu RogerGales 2011-12-24 18:17:53