【问题标题】:Last Five Pages Visited Cookie访问过的最后五页 Cookie
【发布时间】:2009-07-02 22:43:37
【问题描述】:

所以,我有一系列产品页面,我想做的只是将最近查看的 5 个产品存储在 cookie 中,以便可以将其显示为网站历史记录。我遇到的问题不是将五个初始项目添加到 cookie 中,而是当他们查看 6、7 或 10 个项目时。有没有人对如何解决这个问题有任何真正体面的建议?

目前我有这个有缺陷的逻辑(为简洁起见,我已经替换了 cookie 名称 (xxx));

Dim i As Integer = 0
        Dim productcount As Integer = 0

        If HttpContext.Current.Request.Cookies("xxx") Is Nothing Then
            Dim gingernuts As New HttpCookie("xxx")
            gingernuts.Values("productcount") = 0
            gingernuts.Expires = DateTime.Now.AddDays(365)
            HttpContext.Current.Response.Cookies.Add(gingernuts)
        End If

        productcount = HttpContext.Current.Request.Cookies("xxx")("productcount")

        For i = 0 To productcount
            If HttpContext.Current.Request.Cookies("xxx")("product" & i & "") = "" Then
                HttpContext.Current.Response.Cookies("xxx")("product" & i & "") = Request.QueryString("id")
            Else
                HttpContext.Current.Response.Cookies("xxx")("product" & i & "") = HttpContext.Current.Request.Cookies("xxx")("product" & i & "")
            End If
        Next

        If productcount = 5 Then
            HttpContext.Current.Response.Cookies("xxx")("productcount") = 5
            HttpContext.Current.Response.Cookies("xxx")("product0") = ""
        Else
            HttpContext.Current.Response.Cookies("xxx")("productcount") = productcount + 1
        End If

欢迎和赞赏建议和批评。

克里斯

【问题讨论】:

    标签: asp.net vb.net cookies


    【解决方案1】:

    只需使用一个简单的 cookie 值,即最近查看的产品 ID 的逗号分隔列表。 (注意我的 VB.NET 就是这么强大)。

    MostRecentIDs as String() '' // Instance level variables
    Const ListSize = 5
    
    '' // in a method somewhere
    context As HttpContext = HttpContext.Current
    cookie As HttpCookie = context.Request.Cookies("mri")
    mri As Queue(Of String)
    
    If cookie Is Nothing Then
        mri = New Queue(Of String)(cookie.Value.Split(",".ToCharArray())
    Else
        mri = New Queue(Of String)
        cookie = New HttpCookie("mri")
    End If
    
    If mri.Contains(Request.QueryString("id")) Then
    
        If mri.Count >= ListSize Then mri.Dequeue()
    
        mri.Enqueue(Request.QueryString("id"))
    
    End If
    
    MostRecentIDs = mri.ToArray();
    
    cookie.Value = String.Join(",", MostRecentIDs)
    cookie.Expires = DateTime.Now.AddDays(365)
    
    context.Response.Add(cookie)
    
    • 现在您可以通过简单的字符串数组访问最新的产品 ID。
    • 此代码处理尚未创建 cookie 的情况。
    • cookie 本身要小得多。
    • 可以轻松地对列表大小的管理进行参数化。

    上面的代码基于我放入一个空的 ASPX 文件的下面经过测试的 C# 代码:-

    const int listSize = 8;
    string[] _mru;
    
    protected void Page_Load(object sender, EventArgs e)
    {
        HttpCookie cookie = Request.Cookies["mru"];
        Queue<string> mru;
        if (cookie != null)
        {
            mru = new Queue<string>(cookie.Value.Split(','));
        }
        else
        {
            mru = new Queue<string>();
            cookie = new HttpCookie("mru"); 
        }
    
        if (!mru.Contains(Request.QueryString["id"]))
        {
            if (mru.Count >= listSize) mru.Dequeue();
    
            mru.Enqueue(Request.QueryString["id"]);
        }
    
        _mru = mru.ToArray();
    
        cookie.Value = String.Join(",", _mru);
        cookie.Expires = DateTime.Now.AddDays(365);
    
        Response.Cookies.Add(cookie);
    
    }
    

    【讨论】:

    • 嗨 Anthony,我刚开始学习如何为问题选择合适的数据结构。你能解释一下为什么选择队列而不是堆栈吗?当我最初阅读他的问题时,我认为堆栈最适合,因为他想显示用户访问的最后 5 个项目,而堆栈是 LIFO。
    • @Jon,对于最近使用的列表,您需要一个 FIFO 结构。考虑一下,如果达到容量时,您要在插入当前项之前将最后一项从堆栈中弹出。这将导致堆栈中的第一个项目保留在那里,并且一旦达到容量,只有顶部的项目会发生变化。需要的是首先删除列表中最旧的项目,即底部项目而不是顶部项目。首先删除底部项目是 FIFO(队列)而不是 LIFO(堆栈)的操作。
    • 非常感谢您的解释!这是一个很大的帮助,现在非常有意义。
    • 这是一个比我的解决方案更好的解决方案。我刚刚更正了您的实施
    • @Anthony,非常感谢 - 这太棒了,而且效果很好。我从来不知道集合类——但这里有各种各样的东西可以帮助解决一些最不寻常的问题。我会发布VB以供参考.... :)
    【解决方案2】:

    如果我正确理解您的问题,我将这样做:)
    如果产品数量少于 5 个,只需添加新产品。否则将 product0 替换为 product1 直到 4,然后在 4 处添加新产品

        If productcount < 5 Then 'Do the null value check before this
            HttpContext.Current.Response.Cookies("xxx")("productcount") = productCount + 1
            HttpContext.Current.Response.Cookies("xxx")("product" & productCount + 1) = ""
    
        Else
            For i = 0 To productcount - 1
               'Replace product 0 with 1, 1 with 2...till 3 with 4 
                HttpContext.Current.Response.Cookies("xxx")("product" & i & "") = HttpContext.Current.Response.Cookies("xxx")("product" & i + 1& "")
    
           Next
           HttpContext.Current.Response.Cookies("xxx")("product" & 4 & "") =  Request.QueryString("id")
        End If
    

    【讨论】:

      【解决方案3】:

      Anthony 完美地回答了这个问题,但为了将来参考和使用 VB 的人,代码如下:

          Imports System.Collections.Generic
      
          Const listSize As Integer = 5
          Private _mru As String()
      
      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
              Dim cookie As HttpCookie = Request.Cookies("mru")
      
              Dim mru As Queue(Of String)
              If cookie IsNot Nothing Then
                  mru = New Queue(Of String)(cookie.Value.Split(","c))
              Else
                  mru = New Queue(Of String)()
                  cookie = New HttpCookie("mru")
              End If
      
              If mru.Count >= listSize Then
                  mru.Dequeue()
              End If
      
              mru.Enqueue(Request.QueryString("id"))
      
              _mru = mru.ToArray()
      
              cookie.Value = [String].Join(",", _mru)
              cookie.Expires = DateTime.Now.AddDays(365)
      
      
              Response.Cookies.Add(cookie)
      End Sub
      

      也非常感谢这里的所有贡献者。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-13
        • 2012-07-05
        • 1970-01-01
        • 2014-10-15
        • 2011-05-14
        • 1970-01-01
        • 2013-04-08
        • 2016-02-23
        相关资源
        最近更新 更多