GetCookies Safely

The broken code:

HttpCookie cookie = Request.Cookies["cookiename"];
if ( cookie != null && !string.IsNullOrEmpty( cookie.Value ) ) {

The problem: this code will create an entry named “cookiename” in the Request’s Cookies dictionary.  If you’re early enough in the event cycle that it hasn’t copied cookies from Request.Cookies to Response.Cookies, it’ll send your dummy entry with the response to the browser as a new cookie – even if you do nothing else with it!  This is bad.

Why have code like this?  Probably because this:

Response.Cookies["cookiename"] = new Cookie( "cookiename", "somevalue" );

is easier than this:

if ( Response.Cookies["cookiename"] != null ) {
    Response.Cookies["cookiename"] = new Cookie( "cookiename", "somevalue" );
} else {
    Response.Cookies.Add( new Cookie( "cookiename", "somevalue" ) );
}

(But I don’t think the former one works either.)

OK, we’ve identified the problem, how do we fix it?

I’ve created this extension method to get cookies “safely” – e.g. to avoid creating them by accident:

public static HttpCookie GetCookieSafely( this HttpCookieCollection Cookies, string CookieName ) {
    HttpCookie cookie = null;
    if ( new List( Cookies.AllKeys ).Contains( CookieName ) ) {
        cookie = Cookies[CookieName]; // This will create it if it doesn't exist already
    }
    return cookie;
}

Call it like this:

HttpCookie cookie = Request.Cookies.GetCookieSafely( "cookiename" );
if ( cookie != null && !string.IsNullOrEmpty( cookie.Value ) ) {

I’ve written this function a few times, and changed my mind often on what it should look like.  Sometimes I pass in an HttpRequest so usage is Request.GetCookieSafely( "cookiename" ).  Sometimes I extract cookie.Value and just return a string.  Sometimes I look for the cookie like this: if ( Cookies.AllKeys.ToList().Contains( CookieName ) )

What is the “perfect” extension method?  Not sure.  But now I’m not creating cookies in the Request by accident anymore.

Rob