3

I am currently working on a class that helps me creating WebRequest with cookies and POST parameters. But the response.cookies is always empty. How can i grab the returned cookies and send them with the next request?

class WebHandler
{
    private string lasturl = "";
    private Dictionary<string, Cookie> cookies;
    public string lastContent;

    public WebHandler()
    {
        cookies = new Dictionary<string, Cookie>();
    }

    public HttpWebResponse request(string address)
    {
        lasturl = address;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
        foreach (KeyValuePair<string, Cookie> pair in this.cookies)
        {
            Console.WriteLine(" Sent cookie: " + pair.Value.Name + " = " + pair.Value.Value);
            request.CookieContainer.Add(pair.Value);
        }
        request.Method = "GET";
        if(lasturl != "")
            request.Referer = lasturl;

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        foreach (Cookie newCookie in response.Cookies)
        {
            Console.WriteLine(" new cookie: " + newCookie.Name + " = " + newCookie.Value);
            this.cookies[newCookie.Name] = newCookie;
        }
        lastContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
        return response;
    }

    public HttpWebResponse request(string address, Dictionary<string, string> postParameters)
    {
        lasturl = address;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
        foreach (KeyValuePair<string, Cookie> pair in this.cookies)
        {
            Console.WriteLine(" Sent cookie: " + pair.Value.Name + " = " + pair.Value.Value);
            request.CookieContainer.Add(pair.Value);
        }
        request.Method = "POST";

        string postData = "";
        foreach (string key in postParameters.Keys)
            postData += HttpUtility.UrlEncode(key) + "=" + HttpUtility.UrlEncode(postParameters[key]) + "&";


        byte[] data = Encoding.ASCII.GetBytes(postData);
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        foreach (Cookie newCookie in response.Cookies)
        {
            Console.WriteLine(" new cookie: " + newCookie.Name + " = " + newCookie.Value);
            this.cookies[newCookie.Name] = newCookie;
        }
        lastContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
        return response;
    }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
feedc0de
  • 3,646
  • 8
  • 30
  • 55
  • if there is a redirect then yes , you wont get any cookies , try to parse the response headers and u will see cookies , – Hichem Sep 01 '15 at 22:39

3 Answers3

4

Since this.cookies is initially null, your code never enters the loop

foreach (KeyValuePair<string, Cookie> pair in this.cookies)
{
     Console.WriteLine(" Sent cookie: " + pair.Value.Name + " = " + pair.Value.Value);
     request.CookieContainer.Add(pair.Value);
}

Bad part of it that you never see request.CookieContainer is null (Otherwise you would get null reference exception) which would show you something is wrong.

Since request.CookieContainer is null, HttpWebResponse never gets the returned cookies.

Solution: Easy, Just add

if (request.CookieContainer == null) 
         request.CookieContainer = new CookieContainer();

after

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);

PS: You may want to read this question about Naming Conventions in c#.

PS2: in a method request using a variable name request doesn't improve readability.

Community
  • 1
  • 1
I4V
  • 34,891
  • 6
  • 67
  • 79
  • But now i can receive cookies and add the to the next request, but my php script does not see any cookies (but in browser everything works fine). I have to do something with domain maybe? – feedc0de Aug 27 '13 at 18:14
  • Very odd behavior...the response object has a non-null cookie container but no cookies. This definitely worked. – Peter J Feb 26 '16 at 17:43
3

I had the same problem, so I added request.AllowAutoRedirect=false;, now I can get cookies:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
...
request.Method = "POST";
request.AllowAutoRedirect=false;
Madness
  • 2,730
  • 3
  • 20
  • 29
Stephen
  • 115
  • 10
1

If the HttpWebResponse object's Cookies collection is empty, then that means the response had no new cookies. To get access to all cookies for request and response, then read the cookies from the HttpWebRequest object instead, like this:

foreach (Cookie newCookie in request.Cookies)
{
    // Do something with cookies here for next request
}
Karl Anderson
  • 34,606
  • 12
  • 65
  • 80
  • I thought i will get all cookies in the response and have to put the same cookies into the next request? Your example foreaches all cookies in the request (that means NO cookies, becuase nobody sets them). I want to keep the cookies from my old response and add it to the next request! – feedc0de Aug 26 '13 at 17:30
  • Well if you have no cookies in the request and no cookies in the response, then you will have no cookies ever. – Karl Anderson Aug 26 '13 at 17:34