【问题标题】:Check if Cookie Exists检查 Cookie 是否存在
【发布时间】:2012-10-15 01:05:35
【问题描述】:

Stack Overflow 上的快速搜索中,我看到人们建议使用以下方法来检查 cookie 是否存在:

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

或(在Page 类中):

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

但是,当我尝试使用索引器(或 Cookies.Get 方法)检索一个不存在的 cookie 时,它​​似乎实际上 创建 一个具有该名称的“默认”cookie 并返回因此,无论我使用什么 cookie 名称,它都不会返回 null。 (甚至更糟 - 创建一个不需要的 cookie)

我在这里做错了什么,还是有其他方法可以简单地通过名称检查特定 cookie 的存在?

【问题讨论】:

    标签: c# asp.net cookies webforms asp.net-4.0


    【解决方案1】:

    有时您仍然需要知道 Cookie 是否存在于 Response 中。然后你可以检查cookie key是否存在:

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

    更多信息可以在here找到。

    就我而言,我必须在 Global.asax 的 Application_EndRequest 方法中修改响应 Cookie。如果 Cookie 不存在,我不会碰它:

    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
    }
    

    【讨论】:

    • 如果您需要检查响应中生成的 cookie,这是正确的答案。
    • 如果您的 AllKeys 集合不包含 Contains 函数,您可以包含 LINQ (using System.Linq)。
    • 第一个条件语句中的sender 是什么。它在我的控制器方法中显示错误。
    • 你应该使用 Request 而不是 Response。
    【解决方案2】:

    这里有很多正确的答案取决于你想要完成的事情;这是我提供全面答案的尝试:

    RequestResponse 对象都包含Cookies 属性,即HttpCookieCollection 对象。

    Request.Cookies:

    • 此集合包含从客户端收到的 cookie
    • 此集合是只读的
    • 如果您尝试访问此集合中不存在的 cookie,您将收到 null 值。

    Response.Cookies:

    • 此集合仅包含服务器在当前请求期间添加的 cookie。
    • 这个集合是可写的
    • 如果您尝试访问此集合中不存在的 cookie,您将收到一个新的 cookie 对象;如果您尝试访问 DOES NOT 的 cookie 存在于 Request.Cookies 集合中,它将被添加(但如果 Request.Cookies 对象已经包含具有相同键的 cookie,即使它是值已过时,它不会被更新以反映 Response.Cookies 集合中新创建的 cookie 的更改。

    解决方案


    如果要检查客户端是否存在 cookie,请执行以下操作之一

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

    如果您想检查服务器在当前请求期间添加的 cookie 是否存在,请执行以下操作:

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

    正在尝试通过以下方法之一检查服务器在当前请求期间添加的 cookie...

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

    ...将导致在Response.Cookies 集合中创建一个cookie,并且状态将评估为true

    【讨论】:

    • 感谢您的总结。
    • 这是一个很好的总结,与我看到的行为相对应。关于响应的最后一点 - 索引器、getter 和列表 - 是否记录在任何地方?他们可以改变这种行为,我们的代码就会失败。
    • 我找到了调用Response.Cookies.Get("COOKIE_KEY") 的文档,并使用链接更新了答案。 Response.Cookies.Item[String] 的文档没有说明创建新 cookie,但是,我相信它很可能只是在后台调用 Response.Cookies.Get(String)Response.Cookies.AllKeys.Contains(String) 的文档也没有具体提到这种行为,但我怀疑这是因为 AllKeys 只是所有现有 cookie 的 String[],因此 Contains(String) 方法在另一个库中实现。
    【解决方案3】:

    Response.Cookies 包含将发送回浏览器的 cookie。如果您想知道是否存在 cookie,您可能应该查看Request.Cookies

    无论如何,要查看cookie是否存在,您可以检查Cookies.Get(string)但是,如果您在 Response 对象上使用此方法并且 cookie不存在,则将创建该 cookie。

    请参阅 MSDN 参考以获取 HttpCookieCollection.Get Method (String)

    【讨论】:

    • 使用Request 而不是Response seems 以我想要的方式工作。谢谢(两个答案几乎相同,但你先回答了
    • Cookies.Get(string) 的链接文档中的注释表明“如果指定的 cookie 不存在,则此方法会创建一个具有该名称的新 cookie。”
    • @MichaelPetito 虽然文档这么说,但我发现如果找不到它会返回 null 。我相信如果不存在则创建仅在使用响应时适用。如果 Request.Cookies 则 Get 返回 null。您现在可以在该文档上看到一些关于此的用户 cmets。
    • 为什么假设 OP 不想知道响应 cookie 是否存在?也许他们想知道响应中是否已经添加了 cookie。 Get 在问题的上下文中不起作用。
    • Aaron,不管文档怎么说... get 方法的代码是: HttpCookie cookie = (HttpCookie) this.BaseGet(name); if (cookie == null && this._response != null) { cookie = new HttpCookie(name); this.AddCookie(cookie, true); [...] 显然新的 cookie 将被返回,所以只要检查请求是好的,我不会指望收集行为
    【解决方案4】:

    您需要使用HttpContext.Current.Request.Cookies,而不是Response.Cookies

    旁注:cookie 被复制到Response.Cookies.Add 上的请求,这使得检查它们中的任何一个对于新添加的 cookie 的行为相同。但是传入的 cookie 永远不会反映在 Response 中。

    此行为记录在HttpResponse.Cookies 属性中:

    使用 HttpResponse.Cookies 集合添加 cookie 后,即使尚未将响应发送到客户端,该 cookie 也会立即在 HttpRequest.Cookies 集合中可用。

    【讨论】:

    • 谢谢,使用Request 正是我所需要的。 +1
    • 这是我发现的关于 cookie 复制行为的唯一文档 - 谢谢!太恶心了。
    • 是的,并且带有“旁注:”的复制只发生在新的 cookie 上。如果您在响应中更新 cookie,如果 cookie 已经在请求中,它将不会更新请求。如果您有一个框架在同一个请求中多次修改 cookie,这可能会让人头疼。
    【解决方案5】:
    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;
        }
    }
    

    用法:

    Request.Cookies.Exists("MyCookie")
    

    【讨论】:

    • 我在Cookie 类中找不到Exists 方法
    • 这段代码为 Cookie 类创建了一个扩展,它添加了“Exists”方法。扩展真的很酷。
    • 仍然,[] 运算符的代码调用 Get 方法,如果没有找到,则创建一个新的 cookie,这意味着结果永远不会为空,只是一个空 cookie(在 HttpResponse 的情况下)
    • 根据最后的评论,您的退货声明应为return cookieCollection.AllKeys.Contains(name);
    【解决方案6】:

    抱歉,没有足够的代表添加评论,但来自 zmbq 的回答:

    无论如何,要查看cookie是否存在,可以检查Cookies.Get(string),这不会修改cookie集合。

    可能不完全正确,因为 Cookies.Get(string) 实际上会创建一个具有该名称的 cookie,如果它不存在的话。 但是,正如他所说,您需要查看 Request.Cookies,而不是 Response.Cookies 所以,类似:

    bool cookieExists = HttpContext.Current.Request.Cookies["cookie_name"] != null;
    

    【讨论】:

    • 这不正确,它会返回 null:“Cookies.Get(string) 实际上会创建一个具有该名称的 cookie”
    • 我已经了解到,如果不存在则创建适用于 Response.Cookies,但不适用于 Request.Cookies。
    【解决方案7】:

    您可以执行以下操作来找出 cookie 的值:

    Request.Cookies[SESSION_COOKIE_NAME].Value
    

    【讨论】:

      猜你喜欢
      • 2012-05-17
      • 1970-01-01
      • 2011-08-23
      • 2014-10-15
      • 2012-03-10
      • 2014-12-04
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多