asp.net-mvc 如何将 HttpRequestBase 转换为 HttpRequest 对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1452522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I convert an HttpRequestBase into an HttpRequest object?
提问by Pure.Krome
inside my ASP.NET MVC controller, I've got a method that requires an HttpRequestobject. All I have access to is an HttpRequestBaseobject.
在我的 ASP.NET MVC 控制器中,我有一个需要HttpRequest对象的方法。我所能访问的只是一个HttpRequestBase对象。
Is there anyway I can somehow convert this?
无论如何我可以以某种方式转换它吗?
What can/should I do??
我可以/应该做什么??
采纳答案by Kevin Hakanson
Is it your method, so you can re-write it to take HttpRequestBase? If not, you can always get the current HttpRequestfrom HttpContext.Current.HttpRequestto pass on. However, I often wrap access to the HttpContext inside a class like mentioned in ASP.NET: Removing System.Web Dependenciesfor better unit testing support.
这是您的方法,因此您可以重新编写它以采取HttpRequestBase吗?如果没有,您始终可以HttpRequest从源中获取电流HttpContext.Current.HttpRequest以进行传递。但是,我经常将 HttpContext 的访问权限封装在ASP.NET 中提到的类中:移除 System.Web 依赖项以获得更好的单元测试支持。
回答by CountZero
You should always use HttpRequestBase and HttpResponseBase in your application as opposed to the concrete versions which are impossible to test (without typemock or some other magic).
您应该始终在您的应用程序中使用 HttpRequestBase 和 HttpResponseBase ,而不是无法测试的具体版本(没有 typemock 或其他一些魔法)。
Simply use the HttpRequestWrapperclass to convert as shown below.
只需使用HttpRequestWrapper类进行转换,如下所示。
var httpRequestBase = new HttpRequestWrapper(Context.Request);
回答by adamgede
You can just use
你可以使用
System.Web.HttpContext.Current.Request
The key here is that you need the full namespace to get to the "correct" HttpContext.
这里的关键是您需要完整的命名空间才能访问“正确”的 HttpContext。
I know it's been 4 years since this question was asked, but if this will help somebody, then here you go!
我知道这个问题已经过去 4 年了,但如果这对某人有帮助,那么你去吧!
(Edit: I see that Kevin Hakanson already gave this answer...so hopefully my response will help those people who just read answers and not comments.) :)
(编辑:我看到 Kevin Hakanson 已经给出了这个答案……所以希望我的回答能帮助那些只阅读答案而不是评论的人。):)
回答by Klaas
Try to use/create a HttpRequestWrapper using your HttpRequestBase.
尝试使用您的 HttpRequestBase 使用/创建 HttpRequestWrapper。
回答by Mohamed Mansour
To get HttpRequest in ASP.NET MVC4 .NET 4.5, you can do the following:
要在 ASP.NET MVC4 .NET 4.5 中获取 HttpRequest,您可以执行以下操作:
this.HttpContext.ApplicationInstance.Context.Request
回答by Tomas Aschan
Typically when you need to access the HttpContextproperty in a controller action, there is something you can do better design wise.
通常,当您需要HttpContext在控制器操作中访问属性时,您可以在设计上做得更好。
For example, if you need to access the current user, give your action method a parameter of type IPrincipal, which you populate with an Attributeand mock as you wish when testing. For a small example on how, see this blog post, and specifically point 7.
例如,如果您需要访问当前用户,请为您的操作方法提供一个 type 参数IPrincipal,您Attribute可以在测试时根据需要使用 an和 mock填充该参数。有关如何操作的小示例,请参阅此博客文章,特别是第 7 点。
回答by Barbara Post
There is no way to convert between these types.
无法在这些类型之间进行转换。
We had a similar case. We rewrote our classes/web services methods so that they use HttpContextBase, HttpApplicationStateBase, HttpServerUtilityBase, HttpSessionStateBase... instead of the types of close name without the "Base" suffix (HttpContext, ... HttpSessionState). They are a lot easier to handle with home-made mocking.
我们有过类似的案例。我们重写了我们的类/Web 服务方法,以便它们使用 HttpContextBase、HttpApplicationStateBase、HttpServerUtilityBase、HttpSessionStateBase...而不是没有“Base”后缀的关闭名称类型(HttpContext,...HttpSessionState)。通过自制的模拟,它们更容易处理。
I feel sorry you couldn't do it.
我很抱歉你做不到。
回答by Kenn
This is an ASP.Net MVC 3.0 AsyncController which accepts requests, converts the inbound HttpRequestBase MVC object to a System.Web.HttpWebRequest. It then sends the request asynchronously. When the response comes back, it converts the System.Web.HttpWebResponse back into an MVC HttpResponseBase object which can be returned via the MVC controller.
这是一个 ASP.Net MVC 3.0 AsyncController,它接受请求,将入站 HttpRequestBase MVC 对象转换为 System.Web.HttpWebRequest。然后异步发送请求。当响应返回时,它将 System.Web.HttpWebResponse 转换回 MVC HttpResponseBase 对象,该对象可以通过 MVC 控制器返回。
To answer this question explicitly, I guess you'd only be interested in the BuildWebRequest() function. However, it demonstrates how to move through the whole pipeline - converting from BaseRequest > Request and then Response > BaseResponse. I thought sharing both would be useful.
要明确回答这个问题,我猜您只会对 BuildWebRequest() 函数感兴趣。但是,它演示了如何在整个管道中移动 - 从 BaseRequest > Request 转换,然后是 Response > BaseResponse。我认为分享两者会很有用。
Through these classes, you can have an MVC server which acts as a web proxy.
通过这些类,您可以拥有一个充当 Web 代理的 MVC 服务器。
Hope this helps!
希望这可以帮助!
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);
}
}
This is the proxy class which does the heavy lifting:
这是执行繁重工作的代理类:
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();
}
}
}
}
回答by RogerGales
It worked like Kevin said.
它像凯文说的那样工作。
I'm using a static method to retrieve the HttpContext.Current.Request, and so always have a HttpRequestobject for use when needed.
我正在使用静态方法来检索HttpContext.Current.Request,因此总是有一个HttpRequest对象在需要时使用。
Here in Class Helper
这里在课堂助手
public static HttpRequest GetRequest()
{
return HttpContext.Current.Request;
}
Here in Controller
在控制器中
if (AcessoModel.UsuarioLogado(Helper.GetRequest()))
Here in View
在这里查看
bool bUserLogado = ProjectNamespace.Models.AcessoModel.UsuarioLogado(
ProjectNamespace.Models.Helper.GetRequest()
);
if (bUserLogado == false) { Response.Redirect("/"); }
My Method UsuarioLogado
我的方法 UsuarioLogado
public static bool UsuarioLogado(HttpRequest Request)

