ภายในตัวควบคุม ASP.NET MVC ของฉันฉันมีวิธีการที่ต้องใช้HttpRequest
วัตถุ ทั้งหมดที่ฉันสามารถเข้าถึงได้คือHttpRequestBase
วัตถุ
ฉันสามารถแปลงสิ่งนี้ได้หรือไม่?
ทำอะไรได้บ้าง ??
ภายในตัวควบคุม ASP.NET MVC ของฉันฉันมีวิธีการที่ต้องใช้HttpRequest
วัตถุ ทั้งหมดที่ฉันสามารถเข้าถึงได้คือHttpRequestBase
วัตถุ
ฉันสามารถแปลงสิ่งนี้ได้หรือไม่?
ทำอะไรได้บ้าง ??
คำตอบ:
เป็นวิธีการของคุณดังนั้นคุณสามารถเขียนใหม่ได้HttpRequestBase
หรือไม่? ถ้าไม่คุณสามารถรับกระแสHttpRequest
จากHttpContext.Current.HttpRequest
การส่งต่อได้ตลอดเวลา อย่างไรก็ตามฉันมักจะปิดการเข้าถึง HttpContext ภายในคลาสดังที่กล่าวไว้ในASP.NET: Removing System Web Dependenciesเพื่อรองรับการทดสอบหน่วยที่ดีขึ้น
คุณควรใช้ HttpRequestBase และ HttpResponseBase ในแอปพลิเคชันของคุณเสมอเมื่อเทียบกับเวอร์ชันคอนกรีตซึ่งไม่สามารถทดสอบได้ (โดยไม่ใช้ typemock หรือเวทมนตร์อื่น ๆ )
เพียงใช้คลาสHttpRequestWrapperเพื่อแปลงดังที่แสดงด้านล่าง
var httpRequestBase = new HttpRequestWrapper(Context.Request);
HttpRequestBase
และยังHttpResponseBase
HttpContextBase
:)
HttpRequestBase
ฉันจะได้รับที่เกิดขึ้นจริงHttpRequest
จากมันได้หรือไม่
คุณสามารถใช้
System.Web.HttpContext.Current.Request
ที่สำคัญคือคุณต้องมีเนมสเปซแบบเต็มเพื่อไปยัง HttpContext "ถูกต้อง"
ฉันรู้ว่ามันเป็นเวลา 4 ปีแล้วที่คำถามนี้ถูกถาม แต่ถ้าสิ่งนี้จะช่วยใครสักคนได้ก็ไปเลย!
(แก้ไข: ฉันเห็นว่า Kevin Hakanson ให้คำตอบนี้แล้ว ... ดังนั้นหวังว่าคำตอบของฉันจะช่วยให้คนที่เพิ่งอ่านคำตอบและไม่แสดงความคิดเห็น) :)
ลองใช้ / สร้าง HttpRequestWrapper โดยใช้ HttpRequestBase ของคุณ
ในการรับ HttpRequest ใน ASP.NET MVC4 .NET 4.5 คุณสามารถทำสิ่งต่อไปนี้:
this.HttpContext.ApplicationInstance.Context.Request
โดยทั่วไปเมื่อคุณต้องการเข้าถึงHttpContext
คุณสมบัติในการดำเนินการของคอนโทรลเลอร์มีบางสิ่งที่คุณสามารถออกแบบได้ดีกว่าอย่างชาญฉลาด
ตัวอย่างเช่นหากคุณต้องการเข้าถึงผู้ใช้ปัจจุบันให้กำหนดพารามิเตอร์ประเภทวิธีการดำเนินการIPrincipal
ซึ่งคุณเติมข้อมูลAttribute
และล้อเลียนตามที่คุณต้องการเมื่อทำการทดสอบ สำหรับตัวอย่างเล็ก ๆ เกี่ยวกับวิธีการดูโพสต์บล็อกนี้และเฉพาะประเด็นที่ 7
ไม่มีวิธีแปลงระหว่างประเภทเหล่านี้
เรามีกรณีที่คล้ายกัน เราเขียนเมธอดคลาส / เว็บเซอร์วิสของเราใหม่เพื่อให้ใช้ HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ... แทนประเภทของชื่อปิดที่ไม่มีคำต่อท้าย "Base" (HttpContext, ... HttpSessionState) พวกเขาจัดการได้ง่ายกว่ามากด้วยการล้อเลียนแบบโฮมเมด
ฉันรู้สึกเสียใจที่คุณไม่สามารถทำได้
นี่คือ ASP.Net MVC 3.0 AsyncController ซึ่งรับคำขอแปลงอ็อบเจ็กต์ HttpRequestBase ขาเข้าเป็น System.Web.HttpWebRequest จากนั้นจะส่งคำขอแบบอะซิงโครนัส เมื่อการตอบกลับกลับมามันจะแปลง System.Web.HttpWebResponse กลับเป็นอ็อบเจ็กต์ MVC HttpResponseBase ซึ่งสามารถส่งคืนผ่านตัวควบคุม MVC
เพื่อตอบคำถามนี้อย่างชัดเจนฉันเดาว่าคุณสนใจเฉพาะฟังก์ชัน BuildWebRequest () อย่างไรก็ตามมันแสดงให้เห็นถึงวิธีการเคลื่อนผ่านไปป์ไลน์ทั้งหมด - การแปลงจาก BaseRequest> Request จากนั้น Response> BaseResponse ฉันคิดว่าการแบ่งปันทั้งสองอย่างจะเป็นประโยชน์
ผ่านคลาสเหล่านี้คุณสามารถมีเซิร์ฟเวอร์ 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)