HttpRequest与HttpRequestMessage与HttpRequestBase的区别

62

ASP.NET中这些类之间有什么区别?我发现这些类之间没有继承关系。

下面的代码返回一个HttpRequestWrapper实例,它是一个HttpRequestBase并且拥有一个HttpRequest

HttpRequestMessage request = ...;
HttpRequestBase reqBase = (request.Properties["MS_HttpContext"] as HttpContextWrapper).Request;
// do somthing with reqBase.Cookies

微软似乎想要让我们在从 HttpRequestMessage 获取 cookie 时感到恼火。

请问 request.Properties["MS_HttpContext"] 是否一定不会是 null?

或者假设一个 ajax 请求在 ApiController 的 action 中被处理,我可以用两种不同的方法获取客户端的 IP。

var ip = (request.Properties["MS_HttpContext"] as HttpContextWrapper).Request.UserHostAddress

var ip = HttpContext.Current.Request.UserHostAddress

这两者有何区别?
一般而言,我可以用不同的方式去访问相同的请求/响应数据,例如Cookie、Header、请求者信息等等。那么什么情况下该使用哪种方式呢?我们能否说“如果是ajax请求,由于某些原因HttpRequest可能无法正常工作,因此对于ajax请求我们应该使用HttpRequestMessage”?
1个回答

57

HttpRequestPageUserControl类上的仅限GET属性。同样,它自己的大多数属性也是只能获取的(见1)。此类由ASP.NET页面用于获取有关传入http请求的信息,例如读取客户端IP、cookie、查询字符串等。重要的是,它是“旧”的System.Web程序集的一部分,自.NET 1.1以来就存在。

HttpRequestMessage是.NET 4.5中的新功能,它是System.Net的一部分。它可用于客户端和服务端,用于创建、发送和接收HTTP请求和响应。它替代了HttpWebRequest,在.NET 4.5中已过时。

至于HttpRequestBase和HttpRequestWrapper,我只能引用docs来解释:

HttpRequestWrapper类从HttpRequestBase类派生而来,作为HttpRequest类的包装器。该类公开了HttpRequest类的功能,并公开了HttpRequestBase类型。HttpRequestBase类使您能够使用自定义实现(例如,在ASP.NET管道之外执行单元测试时)替换应用程序中的HttpRequest类的原始实现。


4
关于HttpRequest和HttpRequestBase的附加信息: HttpRequestBase上的大多数方法都是虚拟的,这使得在单元测试的上下文中轻松地模拟和存根化该类型。 - leojh
你能找到任何关于 HttpWebRequest 已经过时的官方参考资料吗?我只看到构造函数被列为过时,文档指向使用 WebRequest.Create 代替。 - NStuke
@NStuke 不是很确定,但似乎这是共识:https://dev59.com/QHXYa4cB1Zd3GeqP8J3Z - Filip
1
@Filip - 很有趣,看到反编译的代码显示HttpClient仍在底层使用HttpWebRequest。 - NStuke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接