61

From a quick search on Stack Overflow I saw people suggesting the following way of checking if a cookie exists:

HttpContext.Current.Response.Cookies["cookie_name"] != null

or (inside a Page class):

this.Response.Cookies["cookie_name"] != null

However, when I try to use the indexer (or the Cookies.Get method) to retrieve a cookie that does not exist it seems to actually create a 'default' cookie with that name and return that, thus no matter what cookie name I use it never returns null. (and even worse - creates an unwanted cookie)

Am I doing something wrong here, or is there a different way of simply checking for the existance of a specific cookie by name?

Acidic
  • 6,154
  • 12
  • 46
  • 80

7 Answers7

65

Sometimes you still need to know if Cookie exists in Response. Then you can check if cookie key exists:

HttpContext.Current.Response.Cookies.AllKeys.Contains("myCookie")

More info can be found here.

In my case I had to modify Response Cookie in Application_EndRequest method in Global.asax. If Cookie doesn't exist I don't touch it:

string name = "myCookie";
HttpContext context = ((HttpApplication)sender).Context;
HttpCookie cookie = null;

if (context.Response.Cookies.AllKeys.Contains(name))
{
    cookie = context.Response.Cookies[name];
}

if (cookie != null)
{
    // update response cookie
}
marisks
  • 1,812
  • 1
  • 17
  • 33
59

There are a lot of right answers here depending on what you are trying to accomplish; here's my attempt at providing a comprehensive answer:

Both the Request and Response objects contain Cookies properties, which are HttpCookieCollection objects.

Request.Cookies:

  • This collection contains cookies received from the client
  • This collection is read-only
  • If you attempt to access a non-existent cookie from this collection, you will receive a null value.

Response.Cookies:

  • This collection contains only cookies that have been added by the server during the current request.
  • This collection is writeable
  • If you attempt to access a non-existent cookie from this collection, you will receive a new cookie object; If the cookie that you attempted to access DOES NOT exist in the Request.Cookies collection, it will be added (but if the Request.Cookies object already contains a cookie with the same key, and even if it's value is stale, it will not be updated to reflect the changes from the newly-created cookie in the Response.Cookies collection.

Solutions


If you want to check for the existence of a cookie from the client, do one of the following

  • Request.Cookies["COOKIE_KEY"] != null
  • Request.Cookies.Get("COOKIE_KEY") != null
  • Request.Cookies.AllKeys.Contains("COOKIE_KEY")

If you want to check for the existence of a cookie that has been added by the server during the current request, do the following:

  • Response.Cookies.AllKeys.Contains("COOKIE_KEY") (see here)

Attempting to check for a cookie that has been added by the server during the current request by one of these methods...

  • Response.Cookies["COOKIE_KEY"] != null
  • Response.Cookies.Get("COOKIE_KEY") != null (see here)

...will result in the creation of a cookie in the Response.Cookies collection and the state will evaluate to true.

Trevor
  • 13,085
  • 13
  • 76
  • 99
  • 1
    Thanks for this summary. – Donnelle Jul 22 '15 at 02:57
  • 1
    This is an excellent summary, and corresponds to the behavior I'm seeing. Is the last bit regarding the response - the indexer, the getter and the list - documented anywhere? They could change that behavior and our code would fail. – h bob Sep 21 '15 at 12:58
  • I found documentation for the the call to `Response.Cookies.Get("COOKIE_KEY")` and updated the answer with a link. The documentation for `Response.Cookies.Item[String]` doesn't say anything about creating a new cookie, however, I believe it is most likely just calling `Response.Cookies.Get(String)` under the hood. The documentation for `Response.Cookies.AllKeys.Contains(String)` doesn't mention this behavior specifically either, but I suspect that is because `AllKeys` is just a `String[]` of all existing cookies and the `Contains(String)` method is consequently implemented in another library. – Trevor Sep 21 '15 at 17:04
44

Response.Cookies contains the cookies that will be sent back to the browser. If you want to know whether a cookie exists, you should probably look into Request.Cookies.

Anyway, to see if a cookie exists, you can check Cookies.Get(string). However, if you use this method on the Response object and the cookie doesn't exist, then that cookie will be created.

See MSDN Reference for HttpCookieCollection.Get Method (String)

Liam
  • 27,717
  • 28
  • 128
  • 190
zmbq
  • 38,013
  • 14
  • 101
  • 171
  • 3
    Using `Request` instead of `Response seems` to work the way I want it to. Thanks (*both answers are pretty much the same, but you answered first*) – Acidic Oct 24 '12 at 22:38
  • 16
    The remarks in the linked documentation for `Cookies.Get(string)` indicate "If the named cookie does not exist, this method creates a new cookie with that name." – Michael Petito Apr 24 '13 at 14:41
  • Adding a cookie to the request makes no difference. – zmbq Apr 24 '13 at 20:29
  • 2
    @MichaelPetito While the doc says that, I have found that it returns null if it is not found. I believe the create if not exists only applies when working with response. If Request.Cookies then Get returns null. You can see some user comments on that documentation now regarding that. – AaronLS Oct 04 '13 at 15:42
  • 4
    Why assume the OP doesn't want to know if a response cookie exists? Maybe they want to know if a cookie has already been added to the response. Get doesn't work in the context of the question. – xr280xr May 04 '15 at 16:25
  • Probably because he accepted the answer two and a half years ago. – zmbq May 04 '15 at 18:29
  • 1
    Aaron, whatever the doc says... the code for the get method is: HttpCookie cookie = (HttpCookie) this.BaseGet(name); if (cookie == null && this._response != null) { cookie = new HttpCookie(name); this.AddCookie(cookie, true); [...] clearly the new cookie will be returned, so as far as checking request is good, I wouldn't count on the collection bahavior – mikus Aug 19 '15 at 09:33
  • 1
    @zmbq, It would be helpful if the answer were edited to address some of the comments, or deleted altogether. – GaTechThomas Nov 17 '15 at 16:19
36

You need to use HttpContext.Current.Request.Cookies, not Response.Cookies.

Side note: cookies are copied to Request on Response.Cookies.Add, which makes check on either of them to behave the same for newly added cookies. But incoming cookies are never reflected in Response.

This behavior is documented in HttpResponse.Cookies property:

After you add a cookie by using the HttpResponse.Cookies collection, the cookie is immediately available in the HttpRequest.Cookies collection, even if the response has not been sent to the client.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Thanks, using `Request` is pretty much what I needed. +1 – Acidic Oct 24 '12 at 22:39
  • This is the only documentation I've found of that cookie copying behavior - thank you! It's quite obnoxious. – Evan M Jan 29 '14 at 21:04
  • 7
    Yes, and with that "Side note:" the copying only occurs for new cookies. If you update a cookie in a response, it won't update the request if the cookie was already in a request. This can be a headache if you have a framework that modifies a cookie more than once in the same request. – AaronLS Jul 09 '14 at 21:45
4
public static class CookieHelper
{
    /// <summary>
    /// Checks whether a cookie exists.
    /// </summary>
    /// <param name="cookieCollection">A CookieCollection, such as Response.Cookies.</param>
    /// <param name="name">The cookie name to delete.</param>
    /// <returns>A bool indicating whether a cookie exists.</returns>
    public static bool Exists(this HttpCookieCollection cookieCollection, string name)
    {
        if (cookieCollection == null)
        {
            throw new ArgumentNullException("cookieCollection");
        }

        return cookieCollection[name] != null;
    }
}

Usage:

Request.Cookies.Exists("MyCookie")
Levitikon
  • 7,749
  • 9
  • 56
  • 74
  • I cant Find `Exists` method in `Cookie` class – Imad Aug 14 '14 at 07:52
  • 1
    This code creates an extension to the Cookie class, which adds the "Exists" method. Extensions are really cool. – CigarDoug Aug 22 '14 at 18:17
  • 2
    still, the code for [] operator calls Get method, and this one creates a new cookie if none is found, which means the result will never be null, just an empty cookie (in case of HttpResponse) – mikus Aug 19 '15 at 09:37
  • 2
    As per last comment, your return statement should be `return cookieCollection.AllKeys.Contains(name);` – Chris Walsh Jun 12 '17 at 23:24
2

Sorry, not enough rep to add a comment, but from zmbq's answer:

Anyway, to see if a cookie exists, you can check Cookies.Get(string), this will not modify the cookie collection.

is maybe not fully correct, as Cookies.Get(string) will actually create a cookie with that name, if it does not already exist. However, as he said, you need to be looking at Request.Cookies, not Response.Cookies So, something like:

bool cookieExists = HttpContext.Current.Request.Cookies["cookie_name"] != null;
Fiddles
  • 2,790
  • 1
  • 32
  • 35
  • This is not true, it will return null: "Cookies.Get(string) will actually create a cookie with that name" – AaronLS Oct 03 '13 at 22:11
  • 1
    I have since learned that the create if not exists applies when working with Response.Cookies, but NOT Request.Cookies. – AaronLS Oct 04 '13 at 15:47
0

You can do something like this to find out the cookies's value:

Request.Cookies[SESSION_COOKIE_NAME].Value
Andy
  • 49,085
  • 60
  • 166
  • 233
vargashj
  • 33
  • 6