Sometimes there is a need to send cookies over the line on a call to HttpWebRequest.GetResponse(). The documentation about HttpWebRequest.CookieContainer: "... The CookieContainer property provides an instance of the CookieContainer class that contains the cookies associated with this request." That's really nice to have this support already there! But: how I get it setup on the first request? Often users already have a dozen cookies within their temporary internet files folder managed by Internet Explorer. How can I reuse these?
Bad news: there is no managed code support in the .NET Framwork to get them. Good news: we can use the Windows API support provided in wininet.dll to retrieve the cookies: InternetGetCookie(). So we can define the Interop declaration as follows:
[DllImport("wininet.dll", CharSet=CharSet.Auto , SetLastError=
true)]
public static extern bool InternetGetCookie (
string url, string name, StringBuilder data, ref int dataSize);
That's it. To wrap the call we define a wrapper function:
private
static string RetrieveIECookiesForUrl(string url) {
StringBuilder cookieHeader = new StringBuilder(new String(' ', 256), 256);
int datasize = cookieHeader.Length;
if (!InternetGetCookie(url, null, cookieHeader, ref datasize)) {
if (datasize < 0)
return String.Empty;
cookieHeader = new StringBuilder(datasize); // resize with new datasize
InternetGetCookie(url, null, cookieHeader, ref datasize);
}
return cookieHeader.ToString();
}
OK, now we have the cookie content string, that looks usually like this: "KEY=Value; KEY2=what ever". Now we simply create managed cookies by creating instances of System.Net.Cookie. But stop! Did we really have to parse the cookie content string (aka cookie headers) to create the instances?
Again, good news: no, we did not have to do this. There is already build in support provided by the CookieContainer class we also need to set on the HttpWebRequest! The code:
public static CookieContainer GetCookieContainerForUrl(Uri url) {
CookieContainer container = new CookieContainer();
string cookieHeaders = RetrieveIECookiesForUrl(url.AbsoluteUri);
if (cookieHeaders.Length > 0) {
try { container.SetCookies(url, cookieHeaders); } catch (CookieException){}
}
return container;
}
Done
