In meinem ASP.NET MVC-Controller habe ich eine Methode, die ein HttpRequest
Objekt erfordert . Ich habe nur Zugriff auf ein HttpRequestBase
Objekt.
Kann ich das irgendwie konvertieren?
Was kann / soll ich tun?
In meinem ASP.NET MVC-Controller habe ich eine Methode, die ein HttpRequest
Objekt erfordert . Ich habe nur Zugriff auf ein HttpRequestBase
Objekt.
Kann ich das irgendwie konvertieren?
Was kann / soll ich tun?
Antworten:
Ist es Ihre Methode, damit Sie sie neu schreiben können HttpRequestBase
? Wenn nicht, können Sie immer den Strom HttpRequest
von HttpContext.Current.HttpRequest
weiterleiten lassen. Ich verpacke den Zugriff auf den HttpContext jedoch häufig in eine Klasse wie in ASP.NET: Entfernen von System.Web-Abhängigkeiten, um eine bessere Unterstützung für Komponententests zu erzielen .
Sie sollten in Ihrer Anwendung immer HttpRequestBase und HttpResponseBase verwenden, im Gegensatz zu den konkreten Versionen, die nicht getestet werden können (ohne Typemock oder andere Magie).
Verwenden Sie einfach die HttpRequestWrapper- Klasse, um wie unten gezeigt zu konvertieren.
var httpRequestBase = new HttpRequestWrapper(Context.Request);
HttpRequestBase
und HttpResponseBase
auch verwenden HttpContextBase
. :)
Sie können einfach verwenden
System.Web.HttpContext.Current.Request
Der Schlüssel hier ist, dass Sie den vollständigen Namespace benötigen, um zum "richtigen" HttpContext zu gelangen.
Ich weiß, es ist 4 Jahre her, seit diese Frage gestellt wurde, aber wenn dies jemandem hilft, dann können Sie loslegen!
(Bearbeiten: Ich sehe, dass Kevin Hakanson diese Antwort bereits gegeben hat ... also hoffentlich hilft meine Antwort den Leuten, die nur Antworten und keine Kommentare lesen.) :)
Um HttpRequest in ASP.NET MVC4 .NET 4.5 abzurufen, haben Sie folgende Möglichkeiten:
this.HttpContext.ApplicationInstance.Context.Request
Wenn Sie HttpContext
in einer Controller-Aktion auf die Eigenschaft zugreifen müssen, können Sie in der Regel das Design verbessern.
Wenn Sie beispielsweise auf den aktuellen Benutzer zugreifen müssen, geben Sie Ihrer Aktionsmethode einen Parameter vom Typ IPrincipal
, den Sie Attribute
beim Testen nach Belieben mit einem und verspotten. Ein kleines Beispiel dazu finden Sie in diesem Blog-Beitrag und speziell in Punkt 7.
Es gibt keine Möglichkeit, zwischen diesen Typen zu konvertieren.
Wir hatten einen ähnlichen Fall. Wir haben unsere Klassen- / Webdienstmethoden so umgeschrieben, dass sie HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... anstelle der Typen von engen Namen ohne das Suffix "Base" (HttpContext, ... HttpSessionState) verwenden. Sie sind viel einfacher mit hausgemachtem Spott zu handhaben.
Es tut mir leid, dass du es nicht geschafft hast.
Dies ist ein ASP.Net MVC 3.0 AsyncController, der Anforderungen akzeptiert und das eingehende HttpRequestBase MVC-Objekt in ein System.Web.HttpWebRequest konvertiert. Anschließend wird die Anforderung asynchron gesendet. Wenn die Antwort zurückkommt, konvertiert sie die System.Web.HttpWebResponse zurück in ein MVC HttpResponseBase-Objekt, das über den MVC-Controller zurückgegeben werden kann.
Um diese Frage explizit zu beantworten, interessieren Sie sich vermutlich nur für die Funktion BuildWebRequest (). Es wird jedoch gezeigt, wie Sie sich durch die gesamte Pipeline bewegen - Konvertieren von BaseRequest> Request und dann Response> BaseResponse. Ich dachte, beides zu teilen wäre nützlich.
Über diese Klassen können Sie einen MVC-Server haben, der als Webproxy fungiert.
Hoffe das hilft!
Regler:
[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);
}
}
Dies ist die Proxy-Klasse, die das schwere Heben übernimmt:
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();
}
}
}
}
Es hat funktioniert, wie Kevin gesagt hat.
Ich verwende eine statische Methode, um das abzurufen HttpContext.Current.Request
, und habe daher immer ein HttpRequest
Objekt zur Verwendung, wenn es benötigt wird.
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)