내 ASP.NET MVC 컨트롤러 안에 HttpRequest
개체 가 필요한 메서드가 있습니다. 내가 접근 할 수있는 것은 HttpRequestBase
객체뿐입니다.
어쨌든 내가 어떻게 든 이것을 변환 할 수 있습니까?
무엇을 할 수 있고 /해야합니까 ??
내 ASP.NET MVC 컨트롤러 안에 HttpRequest
개체 가 필요한 메서드가 있습니다. 내가 접근 할 수있는 것은 HttpRequestBase
객체뿐입니다.
어쨌든 내가 어떻게 든 이것을 변환 할 수 있습니까?
무엇을 할 수 있고 /해야합니까 ??
답변:
그것은 당신의 방법입니까, 그래서 그것을 다시 쓸 수 HttpRequestBase
있습니까? 그렇지 않은 경우 항상 전류 HttpRequest
를 가져와 HttpContext.Current.HttpRequest
전달할 수 있습니다. 그러나 ASP.NET : 더 나은 단위 테스트 지원을 위해 System.Web 종속성 제거에 언급 된 것과 같이 클래스 내에서 HttpContext에 대한 액세스를 종종 래핑합니다 .
테스트가 불가능한 구체적인 버전 (typemock 또는 다른 마술없이)과는 반대로 항상 애플리케이션에서 HttpRequestBase 및 HttpResponseBase를 사용해야합니다.
HttpRequestWrapper 클래스를 사용하여 아래와 같이 변환하면됩니다.
var httpRequestBase = new HttpRequestWrapper(Context.Request);
HttpRequestBase
와 HttpResponseBase
도 HttpContextBase
. :)
일반적으로 HttpContext
컨트롤러 작업에서 속성에 액세스해야 할 때 더 나은 디자인 방식으로 수행 할 수있는 작업이 있습니다.
예를 들어 현재 사용자에 액세스해야하는 경우 테스트 할 때 원하는대로 및 mock으로 IPrincipal
채울 유형의 매개 변수를 작업 메서드에 제공합니다 Attribute
. 방법에 대한 간단한 예는 이 블로그 게시물 , 특히 7 번을 참조하십시오 .
이러한 유형간에 변환 할 수있는 방법은 없습니다.
비슷한 경우가있었습니다. 클래스 / 웹 서비스 메서드를 다시 작성하여 "Base"접미사 (HttpContext, ... HttpSessionState)가없는 닫기 이름 유형 대신 HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase ...를 사용합니다. 집에서 만든 조롱으로 처리하기가 훨씬 쉽습니다.
못해서 미안해.
이것은 요청을 받아들이고 인바운드 HttpRequestBase MVC 개체를 System.Web.HttpWebRequest로 변환하는 ASP.Net MVC 3.0 AsyncController입니다. 그런 다음 요청을 비동기 적으로 보냅니다. 응답이 돌아 오면 System.Web.HttpWebResponse를 MVC 컨트롤러를 통해 반환 할 수있는 MVC HttpResponseBase 개체로 다시 변환합니다.
이 질문에 명시 적으로 대답하려면 BuildWebRequest () 함수에만 관심이있을 것 같습니다. 그러나 전체 파이프 라인을 이동하는 방법을 보여줍니다. BaseRequest> 요청에서 응답> 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();
}
}
}
}
Kevin이 말한 것처럼 작동했습니다.
을 검색하기 위해 정적 메서드를 사용 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)