all'interno del mio controller ASP.NET MVC, ho un metodo che richiede un HttpRequest
oggetto. Tutto quello a cui ho accesso è un HttpRequestBase
oggetto.
C'è comunque che posso in qualche modo convertirlo?
Cosa posso / devo fare ??
all'interno del mio controller ASP.NET MVC, ho un metodo che richiede un HttpRequest
oggetto. Tutto quello a cui ho accesso è un HttpRequestBase
oggetto.
C'è comunque che posso in qualche modo convertirlo?
Cosa posso / devo fare ??
Risposte:
È il tuo metodo, quindi puoi riscriverlo per prenderlo HttpRequestBase
? In caso contrario, puoi sempre ottenere la corrente HttpRequest
da HttpContext.Current.HttpRequest
trasmettere. Tuttavia, spesso inserisco l'accesso a HttpContext all'interno di una classe come menzionata in ASP.NET: Rimozione delle dipendenze System.Web per un migliore supporto per i test di unità.
Dovresti sempre usare HttpRequestBase e HttpResponseBase nella tua applicazione al contrario delle versioni concrete che sono impossibili da testare (senza typemock o qualche altra magia).
Usa semplicemente la classe HttpRequestWrapper per convertire come mostrato di seguito.
var httpRequestBase = new HttpRequestWrapper(Context.Request);
HttpRequestBase
e HttpResponseBase
, anche HttpContextBase
. :)
Puoi semplicemente usare
System.Web.HttpContext.Current.Request
La chiave qui è che hai bisogno dello spazio dei nomi completo per ottenere il "corretto" HttpContext.
So che sono passati 4 anni da quando è stata posta questa domanda, ma se questo aiuterà qualcuno, allora eccoti!
(Modifica: vedo che Kevin Hakanson ha già dato questa risposta ... quindi spero che la mia risposta aiuti quelle persone che leggono solo risposte e non commenti.) :)
Per ottenere HttpRequest in ASP.NET MVC4 .NET 4.5, puoi eseguire le operazioni seguenti:
this.HttpContext.ApplicationInstance.Context.Request
In genere, quando è necessario accedere alla HttpContext
proprietà in un'azione del controller, è possibile eseguire operazioni migliori in termini di progettazione.
Ad esempio, se hai bisogno di accedere all'utente corrente, dai al tuo metodo di azione un parametro di tipo IPrincipal
, che inserisci con Attribute
e simula come desideri durante il test. Per un piccolo esempio su come, vedere questo post del blog e in particolare il punto 7.
Non c'è modo di convertire tra questi tipi.
Abbiamo avuto un caso simile. Abbiamo riscritto i nostri metodi di classi / servizi Web in modo che utilizzino HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... invece dei tipi di nome di chiusura senza il suffisso "Base" (HttpContext, ... HttpSessionState). Sono molto più facili da gestire con le prese in giro fatte in casa.
Mi dispiace che tu non l'abbia fatto.
Questo è un ASP.Net MVC 3.0 AsyncController che accetta le richieste, converte l'oggetto HttpRequestBase MVC in ingresso in un System.Web.HttpWebRequest. Quindi invia la richiesta in modo asincrono. Quando la risposta ritorna, converte di nuovo System.Web.HttpWebResponse in un oggetto MVC HttpResponseBase che può essere restituito tramite il controller MVC.
Per rispondere a questa domanda in modo esplicito, immagino che ti interesserebbe solo la funzione BuildWebRequest (). Tuttavia, dimostra come spostarsi attraverso l'intera pipeline, convertendo da BaseRequest> Request e quindi Response> BaseResponse. Ho pensato che condividere entrambi sarebbe stato utile.
Attraverso queste classi, puoi avere un server MVC che funge da proxy web.
Spero che sia di aiuto!
Controller:
[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);
}
}
Questa è la classe proxy che fa il lavoro pesante:
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();
}
}
}
}
Ha funzionato come ha detto Kevin.
Sto usando un metodo statico per recuperare il file HttpContext.Current.Request
, quindi ho sempre un HttpRequest
oggetto da usare quando necessario.
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)