Check if Cookie Exists
Asked Answered
R

7

63

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?

Rempe answered 24/10, 2012 at 22:8 Comment(0)
U
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)

Unbelievable answered 24/10, 2012 at 22:10 Comment(8)
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)Rempe
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."Lanate
Adding a cookie to the request makes no difference.Unbelievable
@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.Katonah
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.Blind
Probably because he accepted the answer two and a half years ago.Unbelievable
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 bahaviorHoyos
@zmbq, It would be helpful if the answer were edited to address some of the comments, or deleted altogether.Nils
C
66

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
}
Cerography answered 7/11, 2012 at 14:59 Comment(4)
This is the right answer if you need to check for a cookie generated in the response.Televisor
If your AllKeys collection doesn't included a Contains function, you can include LINQ (using System.Linq).Leafy
What is that sender in this first condition statement. It is showing error in my controller method.Mistral
You should use Request instead of Response.Coffeecolored
R
60

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.

Remand answered 13/5, 2015 at 18:54 Comment(2)
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.Cleavage
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.Remand
U
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)

Unbelievable answered 24/10, 2012 at 22:10 Comment(8)
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)Rempe
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."Lanate
Adding a cookie to the request makes no difference.Unbelievable
@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.Katonah
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.Blind
Probably because he accepted the answer two and a half years ago.Unbelievable
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 bahaviorHoyos
@zmbq, It would be helpful if the answer were edited to address some of the comments, or deleted altogether.Nils
E
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.

Examinant answered 24/10, 2012 at 22:11 Comment(3)
Thanks, using Request is pretty much what I needed. +1Rempe
This is the only documentation I've found of that cookie copying behavior - thank you! It's quite obnoxious.Human
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.Katonah
S
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")
Silden answered 6/5, 2013 at 13:1 Comment(4)
I cant Find Exists method in Cookie classMacymad
This code creates an extension to the Cookie class, which adds the "Exists" method. Extensions are really cool.Monteux
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)Hoyos
As per last comment, your return statement should be return cookieCollection.AllKeys.Contains(name);Juratory
E
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;
Electrotherapy answered 9/1, 2013 at 6:12 Comment(2)
This is not true, it will return null: "Cookies.Get(string) will actually create a cookie with that name"Katonah
I have since learned that the create if not exists applies when working with Response.Cookies, but NOT Request.Cookies.Katonah
B
0

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

Request.Cookies[SESSION_COOKIE_NAME].Value
Bajaj answered 29/10, 2014 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.