System.Web.HttpCookieCollection 是 System.Web.HttpContext.Current.Request.Cookies 与 System.Web.Mvc.Controller.Controller.Cookies 的类型,用于获取客户端浏览器传递过来的 cookie。
System.Net.CookieCollection 是 System.Net.HttpWebRequest.CookieContainer 中用到的,用于发起 WebRequest 请求时带上 cookie 。
问题场景
在当前的 ASP.NET MVC 程序中将浏览器发过来的 cookie 原封不动地发给后台一个提供服务的站点。以前的做法是在这个 ASP.NET MVC 程序中从 cookie 中读取数据,然后以此数据为参数通过 WCF 调用后台服务。这次我们打算弃用 WCF,直接用 HttpWebRequest 基于简单灵活的 HTTP 来处理。
于是就面临如何传递 cookie 的问题。首先想到的是 HttpWebRequest.CookieContainer,但 CookieContainer 需要的是 CookieCollection,我们在 MVC 程序中通过 Request.Cookies 得到的却是 HttpCookieCollection 。然后,问题就变成了如何将 HttpCookieCollection 转换为 CookieCollection ?
解决过程
在 stackoverflow 上找到了一个解决方法(Sending cookies using HttpCookieCollection and CookieContainer):
logs_code_copy">HttpCookieCollection oCookies = Request.Cookies; for ( int j = 0; j < oCookies.Count; j++ ) { HttpCookie oCookie = oCookies.Get( j ); Cookie oC = new Cookie(); // Convert between the System.Net.Cookie to a System.Web.HttpCookie... oC.Domain = myRequest.RequestUri.Host; oC.Expires = oCookie.Expires; oC.Name = oCookie.Name; oC.Path = oCookie.Path; oC.Secure = oCookie.Secure; oC.Value = oCookie.Value; myRequest.CookieContainer.Add( oC ); }
但是这个繁琐的解决方法看着别扭,用着难受。如果就这样解决问题,一点成就感都没有。哪是享受代码,分明是做一天码农,凑合一天代码。
好的解决方法总是简单的、优雅的,一定有更好的解决方法。抱着这样的信念上下求索,在园子里发现一篇简短的博文(HttpWebRequest 和 Cookie 的一些记录),其中的一段代码让人眼前一亮:
HttpWebRequest.Headers.Add("Cookie", "Cookie的值");
cookie 不就是 http header 中的一段字符串吗?从 这个 http header 中读取出来,放到另一个 http header 中不就行了吗?根本用不到 HttpCookieCollection 与 CookieCollection。
解决方法
直接上代码:
var request = WebRequest.Create("http://ws.cnblogs.com/user/hasblog") as HttpWebRequest; request.Headers.Add("Cookie", Request.Headers["Cookie"]); using (var response = request.GetResponse() as HttpWebResponse) { }
HttpCookieCollection to CookieCollection 的最简单方法就是既不用 HttpCookieCollection,也不用 CookieCollection。