一说到Cookie我想大家都应该知道它是一个保存在客户端,当浏览器请求一个url时,浏览器会携带相关的Cookie达到服务器端,所以服务器是可以操作Cookie的,在Response时,会把Cookie信息输出到客服端。下面我们来看一个demo吧,代码如下:

第一次请求结果如下:

第二次请求结果如下:

到这里我们可以看到第二次请求传入的Cookie正好是第一次请求返回的Cookie信息,这里的cookie信息的维护主要是我们客户端的浏览器,但是在Asp.net程序开发时,Cookie往往是在服务端程序里面写入,就如我的事例代码;很少有用客服端js实现的。现在我们就来看看asp.net服务端是如何实现读写Cookie的。
首先我们来看看HttpRequest的Cookie是如何定义的:
复制代码 代码如下:
public HttpCookieCollection Cookies { 
get { 
EnsureCookies(); 
if (_flags[needToValidateCookies]) { 
_flags.Clear(needToValidateCookies); 
ValidateCookieCollection(_cookies); 
} 
return _cookies; 
} 
} 
这里的Cookie获取主要是调用一个EnsureCookies方法,EnsureCookies放主要是调用
复制代码 代码如下:
// Populates the Cookies property but does not hook up validation. 
internal HttpCookieCollection EnsureCookies() { 
if (_cookies == null) { 
_cookies = new HttpCookieCollection(null, false); 
if (_wr != null) 
FillInCookiesCollection(_cookies, true /*includeResponse*/); 
if (HasTransitionedToWebSocketRequest) // cookies can't be modified after the WebSocket handshake is complete 
_cookies.MakeReadOnly(); 
} 
return _cookies; 
} 
public sealed class HttpCookieCollection : NameObjectCollectionBase 
{ 
internal HttpCookieCollection(HttpResponse response, bool readOnly) : base(StringComparer.OrdinalIgnoreCase) 
{ 
this._response = response; 
base.IsReadOnly = readOnly; 
} 
}
其中这里的FillInCookiesCollection方法实现也比较复杂:
复制代码 代码如下:
internal void FillInCookiesCollection(HttpCookieCollection cookieCollection, bool includeResponse) { 
if (_wr == null) 
return; 
String s = _wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderCookie); 
// Parse the cookie server variable. 
// Format: c1=k1=v1&k2=v2; c2=... 
int l = (s != null) ? s.Length : 0; 
int i = 0; 
int j; 
char ch; 
HttpCookie lastCookie = null; 
while (i < l) { 
// find next ';' (don't look to ',' as per 91884) 
j = i; 
while (j < l) { 
ch = s[j]; 
if (ch == ';') 
break; 
j++; 
} 
// create cookie form string 
String cookieString = s.Substring(i, j-i).Trim(); 
i = j+1; // next cookie start 
if (cookieString.Length == 0) 
continue; 
HttpCookie cookie = CreateCookieFromString(cookieString); 
// some cookies starting with '$' are really attributes of the last cookie 
if (lastCookie != null) { 
String name = cookie.Name; 
// add known attribute to the last cookie (if any) 
if (name != null && name.Length > 0 && name[0] == '$') { 
if (StringUtil.EqualsIgnoreCase(name, "$Path")) 
lastCookie.Path = cookie.Value; 
else if (StringUtil.EqualsIgnoreCase(name, "$Domain")) 
lastCookie.Domain = cookie.Value; 
continue; 
} 
} 
// regular cookie 
cookieCollection.AddCookie(cookie, true); 
lastCookie = cookie; 
// goto next cookie 
} 
// Append response cookies 
if (includeResponse) { 
// If we have a reference to the response cookies collection, use it directly 
// rather than going through the Response object (which might not be available, e.g. 
// if we have already transitioned to a WebSockets request). 
HttpCookieCollection storedResponseCookies = _storedResponseCookies; 
if (storedResponseCookies == null && !HasTransitionedToWebSocketRequest && Response != null) { 
storedResponseCookies = Response.GetCookiesNoCreate(); 
} 
if (storedResponseCookies != null && storedResponseCookies.Count > 0) { 
HttpCookie[] responseCookieArray = new HttpCookie[storedResponseCookies.Count]; 
storedResponseCookies.CopyTo(responseCookieArray, 0); 
for (int iCookie = 0; iCookie < responseCookieArray.Length; iCookie++) 
cookieCollection.AddCookie(responseCookieArray[iCookie], append: true); 
} 
// release any stored reference to the response cookie collection 
_storedResponseCookies = null; 
} 
}
说简单一点它主要调用HttpWorkerRequest的GetKnownRequestHeader方法获取浏览器传进来的Cookie字符串信息,然后再把这些信息根据;来分隔成多个HttpCookie实例。把这些HttpCookie实例添加到传进来的HttpCookieCollection参数。
这里HttpWorkerRequest继承结果如下:
复制代码 代码如下:
