Monday, 21 February 2011

I noticed we had a problem where there were duplicate cookies on my site. One was correct but the other was carrying an empty string.

It took a lot of debugging and use of Fiddler but I found out something very odd with the .NET framework that was causing this problem.

The oddity

It would seem that evaluating the response's cookies creates one if it doesn't already exist. Here's an example:

if (Response.Cookies["myCookie"] == null)
{
var cookie = new HttpCookie("myCookie", "myValue");
cookie.Domain = ".britishdeveloper.co.uk";
cookie.Expires = DateTime.Now.AddDays(7);
Response.Cookies.Add(cookie);
}
//relax because you now have a cookie with the intended domain and expiry. Right?

Line 1 actually creates the myCookie cookie! If you ever evaluate the property indexer it will create that cookie with no value, no expiration, no domain. Nothing, but it will still exist! Fiddler will show you this in your Response headers: Set-Cookie: myCookie. Also, line 1 will always evaluate to false because of this.

How to avoid the blank cookie

If you are checking for its existence you should NOT use the index property as it will make a new cookie if it doesn't exist.

Instead, use this code that star developer Leo discovered to resolve the issue:

if (!Response.Cookies.AllKeys.Contains("myCookie"))
{
var cookie = new HttpCookie("myCookie", "myValue");
cookie.Domain = ".britishdeveloper.co.uk";
cookie.Expires = DateTime.Now.AddDays(7);
Response.Cookies.Add(cookie);
}
//relax because you now have a cookie with the intended domain and expiry. Right? YES!

Line 1 now evaluates if myCookie exists in the collection of all response cookies rather than accessing (and creating) it directly. So now you know, hopefully it won’t cause you the hours of debugging it cost myself and Leo.

Note: This is not true of Request.Cookies - only Response.Cookies. Lovely bit of inconsistency there