Question

I'm working on a cross platform app targeting windows phone8, windows 8, android and Ios. The app needs to get some data from the internet and reuse the data accordingly. So I have a project with few classes inside. One class to Sign in to the website and get the required cookies for further use. Below is the code from this class:-

public static CookieContainer Cookiejar { get; private set; }

    public static async Task<CookieContainer> GetCookies()
    {
        var uri = new Uri("https://mywebsite.com");
        Cookiejar = new CookieContainer();
        var handler = new HttpClientHandler
        {
            CookieContainer = Cookiejar,
            UseCookies = true,
            UseDefaultCredentials = false
        };
        var client = new HttpClient(handler);
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
        HttpContent content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string,string>("username","user"),
            new KeyValuePair<string,string>("password","user1234"),
            new KeyValuePair<string,string>("customer","AAAA"),
            new KeyValuePair<string,string>("doLogin","Logga+in"),
            new KeyValuePair<string,string>("language","se")
        });
        await client.PostAsync(uri, content);
        return Cookiejar;
    }

Another class is used to get the actual data. I'm passing the CookieContainer from the first class which has CookieHandler as name to the other class which has DataHandler as name. The problem I'm facing is when I use this code in windows phone 8 project and whenever I call httpclient getasync it acts as if I didn't pass the cookies and reset it to xxxxx and the response will be only the log-in page instead of my desired page. Below is the code for DataHandler class:-

public string Response { get; private set; }

    public async Task<string> GetResponse(Uri uri)
    {
        HttpClientHandler handler = new HttpClientHandler();
        handler.UseCookies = true;
        handler.CookieContainer = CookieHandler.Cookiejar;
        HttpClient client = new HttpClient(handler);
        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xhtml+xml"));
        var response = await client.GetAsync(uri);
        string webresponse = null;
        if (response.IsSuccessStatusCode)
        {
            var resp = response.Content.ReadAsByteArrayAsync().Result;
            Encoding encode = Encoding.GetEncoding("iso-8859-1");
            var respString = encode.GetString(resp, 0, resp.Length - 1);
            webresponse = respString;
        }
        handler.Dispose();
        client.Dispose();
        response.Dispose();
        return Response = webresponse;
    }

Been looking into this problem for few hours now and tested every possible tips I found here and on the net, but nothings work. OBS!!! the cookies are not HtmlOnly and not secure. What really gets me confused is the fact that if I use this exact same code in a windows 8 project it works perfectly but not in windows phone 8 project. Worth noting i'm using the latest BCL system.net.http lib.

Any help and suggestions are more than welcome.

Was it helpful?

Solution

Just wanted to answer this question which might be bothering other developers around the World.

First i would like to thank TheESJ for heading me to the right direction.

Now lets start with what i changed/added to my code to workaround this problem.

I just added the following code lines to my initial POST method:-

var wwwUri = new Uri("https://www.mywebsite.com");
Cookiejar.SetCookies(baseUri, Cookiejar.GetCookieHeader(wwwUri));

It appears that in Windows Phone there is '.' in the cookie header (description below), the above code will make a copy of your cookies with the correct header.

Before I applied the above code lines and the CookieContainer in debugger and look at the m_domainTable it had one item with a value {[.mywebsite.com, System.Net.PathList]} eventhough the domain property value is ‘mywebsite.com’ without ‘.’, while in Windows store app it hade one item with a value {[mywebsite.com, System.Net.PathList]} and the domain property value is ‘mywebsite.com’.

After I applied the above code and it worked I debugged and check CookieContainer, the m_domainTable have now two items, one with this value {[.mywebsite.com, System.Net.PathList]} with the domain property value is ‘mywebsite.com’ and the other with this value {[mywebsite.com, System.Net.PathList]} and the same domain property value. That is why it’s sending the right cookie now as it is sending the 2nd cookie {[mywebsite.com, System.Net.PathList]}.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top