【背景】
之前写了些关于模拟登陆,包括使用C#代码实现,的教程:
【教程】模拟登陆网站 之 C#版(内含两种版本的完整的可运行的代码)
然后,发现很多人,对于如何用C#自动处理cookie,很不熟悉,为了统一回答这类的问题,即:
如何写C#代码去(自动)处理cookie?
其实,这个问题的答案,我早就给出了。只是很多人没注意罢了。
因为我早就给出了相关的库:
http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
其中就有自动管理cookie的代码的。
在此,特地,专门的抽出来,给你们解释,如何用C#代码,去处理cookie:
核心代码是:
using System.Net;
using System.Web;
public CookieCollection curCookies = new CookieCollection();
/**************************************************************************************************/
/*
* following functions are helper functions to handle cookie
*
* these functions are extracted from:
* http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
* detail about crifanLib.cs can refer:
* https://www.crifan.com/crifan_released_all/crifanlib/
* */
//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:
* http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
*/
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