feedc0de
feedc0de

Reputation: 3806

WebResponse does not return any cookies

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;
    }
}

Upvotes: 3

Views: 8068

Answers (3)

Stephen
Stephen

Reputation: 115

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;

Upvotes: 3

I4V
I4V

Reputation: 35363

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.

Upvotes: 4

Karl Anderson
Karl Anderson

Reputation: 34844

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
}

Upvotes: 1

Related Questions