If you have used the Windows Phone CookieContainer for stateful communication towards a site / service that does not have a www prefix (which of course many of them don't), you may have noticed that this does not work. A bug in the CookieContainer stores the domain with an erroneous name making it impossible for the cookies to be found at lookup on the same domain occurs.

The example above shows how the domain name for http://mgmobil.golf.se is stored with a leading "." in the collection.

The bug is known by Microsoft and has existed before in previous versions of the .NET Framework (discussed here http://tinyurl.com/cookiecontainerbug771651 and herehttp://tinyurl.com/cookiecollectionbug ). I was hoping that the bug would be resolved with Microsoft now releasing Windows Phone 8.1 and at the same time what is called Universal Apps. Unfortunately it seems not to be the case, which will involve incompatible and opaqueness functionality between Windows Phone and Windows 8, which does not hold the same problem.

A solution to this problem is to single-handedly manage cookies and write these in the header when calling against sites that do not have the www prefix. For HttpClient (which exists as default in WP 8.1 or https://www.nuget.org/packages/Microsoft.Net.Http for WP8) I have written custom HttpClientHandler which can be used in one its constructors.

public class CookieEnabledHttpClientHandler : HttpClientHandler { private readonly CookieCollection cookieCollection;

public CookieEnabledHttpClientHandler() { UseCookies = true; CookieContainer = new CookieContainer(); cookieCollection = new CookieCollection(); }

protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if(!UseCookies) return await base.SendAsync(request, cancellationToken);

SetCookies(request);

var response = await base.SendAsync(request, cancellationToken);

ParseResponse(response);

return response; }

public void SetCookies(HttpRequestMessage request) { if (CookieContainer.GetCookies(request.RequestUri.GetLeftPart()).Count > 0) return;

if (cookieCollection.Count == 0) return;

var cookieString = new StringBuilder();

foreach (var cookie in cookieCollection) { cookieString.Append(cookie); cookieString.Append("; "); }

request.Headers.Add("cookie", cookieString.ToString().TrimEnd(' ', ';')); }

public void ParseResponse(HttpResponseMessage responseMessage) { if (CookieContainer.GetCookies(responseMessage.RequestMessage.RequestUri.GetLeftPart()).Count > 0) return;

if (!responseMessage.Headers.Contains("Set-Cookie")) return;

var cookies = responseMessage.Headers.GetValues("Set-Cookie");

foreach (var cookie in cookies) { foreach (var cookieString in Regex.Split(cookie, ", ")) { var newCookie = new Cookie();

foreach (var value in cookieString.Split(';'). Select(cookiePartString => cookiePartString.Trim().Split('='))) { switch (value[0].ToLower()) { case "expires": newCookie.Expires = DateTime.Parse(value[1]); continue; case "domain": newCookie.Domain = value[1]; continue; case "path": newCookie.Path = value[1]; continue; case "httponly": newCookie.HttpOnly = true; continue; default: newCookie.Name = value[0]; newCookie.Value = value[1]; continue; } }

cookieCollection.Add(newCookie); } } } }

The HttpHandler will check if the cookies are found for the specific domain and in that case not use the custom functionality. The handler can be called using the HttpClient like this:

var client = new HttpClient(new CookieEnabledHttpClientHandler());