【背景】
之前写了些关于模拟登陆,包括使用C#代码实现,的教程:
【教程】模拟登陆网站 之 C#版(内含两种版本的完整的可运行的代码)
然后,发现很多人,对于如何用C#自动处理cookie,很不熟悉,为了统一回答这类的问题,即:
如何写C#代码去(自动)处理cookie?
其实,这个问题的答案,我早就给出了。只是很多人没注意罢了。
因为我早就给出了相关的库:
http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
其中就有自动管理cookie的代码的。
在此,特地,专门的抽出来,给你们解释,如何用C#代码,去处理cookie:
核心代码是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | using System.Net; using System.Web; public CookieCollection curCookies = new CookieCollection(); /**************************************************************************************************/ /* * following functions are helper functions to handle cookie * * these functions are extracted from: * detail about crifanLib.cs can refer: * */ //add a single cookie to cookies, if already exist, update its value public void addCookieToCookies(Cookie toAdd, ref CookieCollection cookies, bool overwriteDomain) { bool found = false ; if (cookies.Count > 0) { foreach (Cookie originalCookie in cookies) { if (originalCookie.Name == toAdd.Name) { // !!! for different domain, cookie is not same, // so should not set the cookie value here while their domains is not same // only if it explictly need overwrite domain if ((originalCookie.Domain == toAdd.Domain) || ((originalCookie.Domain != toAdd.Domain) && overwriteDomain)) { //here can not force convert CookieCollection to HttpCookieCollection, //then use .remove to remove this cookie then add // so no good way to copy all field value originalCookie.Value = toAdd.Value; originalCookie.Domain = toAdd.Domain; originalCookie.Expires = toAdd.Expires; originalCookie.Version = toAdd.Version; originalCookie.Path = toAdd.Path; //following fields seems should not change //originalCookie.HttpOnly = toAdd.HttpOnly; //originalCookie.Secure = toAdd.Secure; found = true ; break ; } } } } if (!found) { if (toAdd.Domain != "" ) { // if add the null domain, will lead to follow req.CookieContainer.Add(cookies) failed !!! cookies.Add(toAdd); } } } //addCookieToCookies //add singel cookie to cookies, default no overwrite domain public void addCookieToCookies(Cookie toAdd, ref CookieCollection cookies) { addCookieToCookies(toAdd, ref cookies, false ); } //check whether the cookies contains the ckToCheck cookie //support: //ckTocheck is Cookie/string //cookies is Cookie/string/CookieCollection/string[] public bool isContainCookie( object ckToCheck, object cookies) { bool isContain = false ; if ((ckToCheck != null ) && (cookies != null )) { string ckName = "" ; Type type = ckToCheck.GetType(); //string typeStr = ckType.ToString(); //if (ckType.FullName == "System.string") if (type.Name.ToLower() == "string" ) { ckName = ( string )ckToCheck; } else if (type.Name == "Cookie" ) { ckName = ((Cookie)ckToCheck).Name; } if (ckName != "" ) { type = cookies.GetType(); // is single Cookie if (type.Name == "Cookie" ) { if (ckName == ((Cookie)cookies).Name) { isContain = true ; } } // is CookieCollection else if (type.Name == "CookieCollection" ) { foreach (Cookie ck in (CookieCollection)cookies) { if (ckName == ck.Name) { isContain = true ; break ; } } } // is single cookie name string else if (type.Name.ToLower() == "string" ) { if (ckName == ( string )cookies) { isContain = true ; } } // is cookie name string[] else if (type.Name.ToLower() == "string[]" ) { foreach ( string name in (( string [])cookies)) { if (ckName == name) { isContain = true ; break ; } } } } } return isContain; } //isContainCookie // update cookiesToUpdate to localCookies // if omitUpdateCookies designated, then omit cookies of omitUpdateCookies in cookiesToUpdate public void updateLocalCookies(CookieCollection cookiesToUpdate, ref CookieCollection localCookies, object omitUpdateCookies) { if (cookiesToUpdate.Count > 0) { if (localCookies == null ) { localCookies = cookiesToUpdate; } else { foreach (Cookie newCookie in cookiesToUpdate) { if (isContainCookie(newCookie, omitUpdateCookies)) { // need omit process this } else { addCookieToCookies(newCookie, ref localCookies); } } } } } //updateLocalCookies //update cookiesToUpdate to localCookies public void updateLocalCookies(CookieCollection cookiesToUpdate, ref CookieCollection localCookies) { updateLocalCookies(cookiesToUpdate, ref localCookies, null ); } /**************************************************************************************************/ /* * 1. following code is to demo how to auto handle cookie * 2. for full code, can found at: * function: _getUrlResponse in: */ public HttpWebResponse getUrlResponse( string url, ......) { //here just make it simple for demo how to auto handle cookie //here shoud init http request //code like this: //HttpWebResponse resp = null; //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); //then added necessary parameter setting, like accept, auto redirect, ... if (curCookies != null ) { req.CookieContainer = new CookieContainer(); req.CookieContainer.PerDomainCapacity = 40; // following will exceed max default 20 cookie per domain req.CookieContainer.Add(curCookies); } //...... //do what you want to to get http response //that is some thing like: //resp = (HttpWebResponse)req.GetResponse(); //...... //update latest cookie into current cookie updateLocalCookies(resp.Cookies, ref curCookies); //then do something like, get response stream, .... } |
【总结】
总之,还是要自己多实践,才能真正理解的。
转载请注明:在路上 » 【整理】C#中如何自动处理cookie