How do I carry a cookie from a System.Net.HttpWebResponse to the next System.Net.HttpWebRequest?

lincolnk picture lincolnk · May 15, 2012 · Viewed 7.9k times · Source

I'm trying to do some automated web requests and need to maintain a cookie from one to the next. I can see that I'm getting back the cookie I want from the initial response, but I can't attach it to the next request.

c# code

// response part

using (var wresp = (System.Net.HttpWebResponse)wrequest.GetResponse())
{

    // respblob gets returned and is accessible to the next request
    respblob.CookieList = new List<System.Net.Cookie>(); 

    foreach (System.Net.Cookie cook in wresp.Cookies)
    {
        respblob.CookieList.Add(cook);
    }

    // ... more stuff not related to cookies
}


// next request part
   var wrequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);

    wrequest.Method = "POST";
    wrequest.ContentType = "application/x-www-form-urlencoded";

    wrequest.CookieContainer = new System.Net.CookieContainer();

    // request.CookieList contains one cookie as expected 
    // from the previous response
    for (int j = 0; j < request.CookieList.Count; j++)
    {
        wrequest.CookieContainer.Add(request.CookieList[j]);
    }


// .... write data to request body

// ... complete the request, etc

here is a recorded exchange for the two request/response actions.

request:

GET http://domain.com/Login.aspx?ReturnUrl=%2fDefault.aspx HTTP/1.1
Host: domain.com
Connection: Keep-Alive

response:

HTTP/1.1 200 OK
Date: Tue, 15 May 2012 17:17:52 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Set-Cookie: ASP.NET_SessionId=zzz4fpb4alwi1du2yavx5tah; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 24408



...html content...

next request:

POST http://domain.com/Login.aspx?ReturnUrl=%2fDefault.aspx HTTP/1.1
Host: domain.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 979
Expect: 100-continue

__LASTFOCUS=&__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=viewstateclipped&__EVENTVALIDATION=validationclipped&ctl00%2524ContentPlaceHolder1%2524Login1%2524LoginButton=&ctl00%2524ContentPlaceHolder1%2524Login1%2524UserName=my.email%40example.com&ctl00%2524ContentPlaceHolder1%2524Login1%2524Password=myPassword

So even though the cookie exists in the HttpWebRequest CookieContainer, it doesn't get sent with the request. What am I doing wrong?

Answer

Darin Dimitrov picture Darin Dimitrov · May 15, 2012

You should use the same CookieContainer instance for the both HttpWebRequest objects that you are using. simply create a CookieContainer instance once:

var cookieContainer = new CookieContainer();

and then have your both request objects use this instance:

var request1 = (HttpWebRequest)WebRequest.Create("http://example.com/url1");
// assign the cookie container for the first request
request1.CookieContainer = cookieContainer;
... go ahead and send the request and process the response


var request2 = (HttpWebRequest)WebRequest.Create("http://example.com/url2");
// reuse the same cookie container instance as the first request
request2.CookieContainer = cookieContainer;
... go ahead and send the request and process the response

Since you are using the same CookieContainer for the both requests, when the first request stores the cookie in this container, the cookie will be emitted alongside the second request automatically. This of course assumes that the second request is to the same domain as the first one.

Also since the cookie is a session cookie (HttpOnly flag) you cannot read its value from the client.