【问题标题】:Display recently viewed items显示最近查看的项目
【发布时间】:2016-03-11 07:51:46
【问题描述】:

我有一个 Product 表,其中包含许多产品。我的 HomeController 中有一个详细信息操作方法,它在详细信息视图页面中返回产品详细信息。

假设:我有这些数据:

ProductID | ProductName | Price | CategoryId
    1     |  T-Shirt    |  120  |  Clothing
    2     |   Shirt     |  150  |  Clothing
    3     |   Watch     |  220  |  Watches
    4     |  Laptop     |  820  |  Computing
    5     | Samsung S6  |  520  |  Mobile
    6     |    Xbox     |  320  |  Gaming

现在,我想要的是,如果某些用户访问 T 恤,那么我想将该 T 恤产品添加到“最近浏览”的新 <div> 中。如果他再次访问“手表”,请在“最近浏览”中添加手表产品<div>

我还想根据他最近浏览的产品展示更多产品。我的意思是,如果他正在访问 Xbox,那么 Xbox 将被添加到最近查看的 <div> 中,并且更多与“游戏”类别相关的产品将显示在最近查看的 <div> 下方的新 <div> 中。

这是我正在尝试的,我的想法是将 productId 存储在 cookie 和详细信息视图页面中,获取 Cookie 请求,从 cookie 获取 productId 并找到该产品的类别并显示更多产品那个类别。

HomeController

public ActionResult Details(int? id)
    {
        if (id == null)
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        Product product = db.Products.Find(id);
        if (product == null)
            return HttpNotFound();

        //Creating cookies
        HttpCookie _userActivity = new HttpCookie("UserActivity");
        _userActivity["ProductID"] = id.ToString();
        _userActivity["ProdutName"] = product.Name;
        _userActivity["Lastvisited"] = DateTime.Now.ToShortTimeString();

        //Adding Expire Time of cookies
        _userActivity.Expires = DateTime.Now.AddDays(5);

        //Adding cookies to current web response
        Response.Cookies.Add(_userActivity);

        //Reading cookies
        HttpCookie readcookie = Request.Cookies["UserActivity"];
        string productID , productName, lastVisited ;
        if (readcookie != null)
        {
            productID = readcookie["ProductID"];
            productName = readcookie["ProdutName"];
            lastVisited = readcookie["Lastvisited"];
        }

        return View(product);
    }

我在我的详细信息视图页面中写了这个。它显示我最近查看产品的 ID 和详细信息,但只有 1 个产品的详细信息来自 cookie。不像我认为的那样

<div class="row">
        <div class="col-sm-9">
            @{
                var product = Request.Cookies["UserActivity"].Values;
            }
            <p>@product</p>

            <br />
            <h2>@Html.DisplayFor(model => model.Name)</h2>
 </div>

【问题讨论】:

  • 看看你的 cookie。您已经对其进行了结构化,使其仅存储一个 ProductId 的信息。如果您想存储多个产品的信息,您将需要存储某种集合而不是单个 Id。
  • @mason 对不起,我没明白你的意思。你能举个例子说明你想说什么吗?
  • 查看您在 cookie 中存储的内容。您正在存储一个 ProductId。如果您仅将其结构化为存储一个 ID,您希望它如何显示所有最近访问的产品?
  • 每次你写一个同名的cookie时,你都会覆盖已经存在的cookie(因此你只有最后一个productid)。这就是梅森想说的(希望我是对的)。您应该将一些 productId 列表存储到 cookie 中,或者更好地使用其他机制将最近的 productId 列表传递给 View(可能通过 ViewData)。
  • @Jure 是的,你是对的。我做错了。如何使用 ViewData 做到这一点?你能写一个例子吗?

标签: c# asp.net asp.net-mvc asp.net-mvc-4 cookies


【解决方案1】:

首先你应该做一些类来保存你最近的产品信息:

public class RecentProduct
{
    public int ProductId { get; set; }

    public string ProdutName { get; set; }

    public DateTime LastVisited { get; set; }
}

可能在加载时或登录事件的某处用用户持久的最近产品列表填充 Session["RecentProductList"]。

那么你就有了根据提供的信息存储最近产品的功能:

public void AddRecentProduct(List<RecentProduct> list, int id, string name, int maxItems)
{
    // list is current list of RecentProduct objects
    // Check if item already exists
    var item = list.FirstOrDefault(t => t.ProductId == id);
    // TODO: here if item is found, you could do some more coding
    //       to move item to the end of the list, since this is the
    //       last product referenced.
    if (item == null)
    {
        // Add item only if it does not exist
        list.Add(new RecentProduct
        {
            ProductId = id,
            ProdutName = name,
            LastVisited = DateTime.Now,
        });
    }

    // Check that recent product list does not exceed maxItems
    // (items at the top of the list are removed on FIFO basis;
    // first in, first out).
    while (list.Count > maxItems)
    {
        list.RemoveAt(0);
    }
}

然后您可以将控制器的代码最小化以获取详细信息:

public ActionResult Details(int? id)
{
    if (id == null)
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    Product product = db.Products.Find(id);
    if (product == null)
        return HttpNotFound();

    // Read list of recent products from session
    var list = Session["RecentProductList"] as List<RecentProduct>;
    if (list == null)
    {
        // If list not found in session, create list and store it in a session
        list = new List<RecentProduct>();
        Session["RecentProductList"] = list;
    }

    // Add product to recent list (make list contain max 10 items; change if you like)
    AddRecentProduct(list, id.Value, product.Name, 10);

    // Store recentProductList to ViewData keyed as "RecentProductList" to use it in a view
    ViewData["RecentProductList"] = list;
    return View(product);
}

然后在您的视图中从 ViewData 字典中读取数据并显示最近产品列表:

<div class="row">
    <div class="col-sm-9">
        @{
            var recentProductList = ViewData["RecentProductList"] as List<RecentProduct>;
        }
        @* Do whatever you like with recentProductList here (e.g. display its data) *@
        @foreach (var recentProduct in recentProductList)
        {
            <p>@recentProduct.ProdutName (id: @recentProduct.ProductId)</p>
        }

        <br />
        <h2>@Html.DisplayFor(model => model.Name)</h2>
    </div>
</div>

当然,此代码示例缺少一些 null 检查和其他内容,但它应该让您大致了解如何使用此功能。

【讨论】:

  • 我喜欢将最近的产品存储在数据库中的想法,但我想这可能只适用于注册用户,我将如何管理访客访客?
  • 对于来宾用户,您还可以将用户信息写入数据库(有限,可能只是一些名称),以便获得一些用户标识符 (ID)。然后将此 ID 存储在 cookie 中,并根据 cookie 中的值,您将获得该访客用户拥有的最新产品列表。例如,用户标识符可以是 GUID。
  • 我只获得了我目前正在查看的产品的详细信息。我怎样才能将recentProductList 存储在cookie 或会话中?我很抱歉,但我做不到。能不能只写代码行。
  • 您在哪里只能获取您正在查看的产品的详细信息?我在视图代码中编写了 foreach 循环,以向您展示如何显示最近产品的列表。在@Html.DisplayFor 中,您可以获得当前产品的当前模型显示的属性。您没有将完整的 recentProductList 存储到 cookie。您仅根据某些用户标识符存储对此最近列表的引用。这是一种方法。我相信还有很多其他人。
  • 我正在获取我当前正在查看的产品的产品名称和 ID。如果我转到Product A 详细信息页面然后它显示Product A (id: 1) 然后当我转到另一个产品的页面时可以说Product B 然后它显示Product B (id: 2),这里应该显示Product A 因为我最近查看了Product A
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多