しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET の Response.Cookies を弄ると空のクッキーが生成されて困った話

ASP.NET で Response.Cookies にとある名前のクッキーが既に入っているかをチェックするコードを書いたところ、空っぽのセッションクッキーが作られることに気が付きました。

例を挙げると以下のようなコードを書いた時です。

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Response.Cookies["hoge"] != null)
        {
            // 何かする
        }
    }
}

やりたいことは既にクッキーが発行されているかのチェックなのですが、どうもインデクサで触った瞬間にクッキーが作られてしまうようです。

実際に動かすと、空のクッキーが発行されているのが確認できます。

f:id:shiba-yan:20150114124727p:plain

RCW 経由で COM のインデクサを使った時にメモリリークしたのを思い出しました。

Request.Cookies を使う時と同じような感覚で使うと、ちょっとめんどくさいことになるようです。なので AllKeys をまずチェックしてから値を取り出すような拡張メソッドを書きました。

public static class HttpCookieExtension
{
    public static bool Contains(this HttpCookieCollection cookies, string name)
    {
        return cookies.AllKeys.Any(p => p == name);
    }

    public static HttpCookie Peek(this HttpCookieCollection cookies, string name)
    {
        return cookies.AllKeys.Any(p => p == name) ? cookies[name] : null;
    }
}

色々とメソッドが足りていないので、やっぱり HttpCookieCollection って古いコレクションなんだと実感出来ますね。きっと中身は NameValueCollection とかになってるんでしょう。

先ほどの例のようにクッキーが既に返されているかチェックする処理は、以下のように書けます。

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Response.Cookies.Contains("hoge"))
        {
            // 何かする
        }
    }
}

これで新しくクッキーが作成されることなく弄ることが出来ました。