【问题标题】:View state data being lost on a back click in MVC查看在 MVC 中单击后丢失的状态数据
【发布时间】:2015-05-21 22:33:07
【问题描述】:

问题背景:

我有一个购物车系统,允许人们更新购物车中每件商品的数量。这是通过来自ViewCartContents.cshtml 视图的AJAX POST 请求向我的控制器上名为UpdateAllCartItems 的方法发出的。所有项目都保存在名为“Cart”的会话变量的列表中。

问题:

如果用户将单个商品添加到他们的购物车(即 1 个单位)然后决定将数量更新为 5,则存储在会话列表中的购物车项目对象的购物车数量属性从 1 更新为 5。问题来了当用户点击另一个页面然后点击返回按钮到购物车并且购物车数量回到1 而不是 5.我可以确认如果我刷新页面然后金额是正确的所以会话正在正确更新,只是看起来视图数据不正确。

以下图片显示了问题

1) 用户将商品添加到购物车:

2) 用户将商品数量更新为 5,购物车总数也更新为 5 件商品的价格:

3) 用户点击网站上的不同页面,然后点击返回按钮返回购物车。商品数量已恢复为1,合计也只显示1件的价格,显然这是不正确的。

守则:

AJAX 发布请求:

$(".updateCart").click(function () {

    $("tr.item").each(function () {

        var $prodId = $(this).find("td.prodId").html();
        var $prodQty = $(this).find("input").val();

        $.ajax({
            url: '@Url.Action("UpdateAllCartItems")',
            type: 'POST',
            data: {
                "id": $prodId,
                "qty": $prodQty
            },

            success: function (updatedCart) {

                document.getElementById("CartList").innerHTML = "";

                for (var i = 0; i < updatedCart.cartItems.length; i++) {
                    AddItemsToCartDropDown(updatedCart.cartItems[i].CartItemName, updatedCart.cartItems[i].CartItemQty, updatedCart.cartItems[i].CartItemPrice);
                }

                var html = '<span class="pull-left glyphicon glyphicon glyphicon-shopping-cart" id="CartItemsTotal"></span> <b>' + updatedCart.cartItems.length + '</b> item(s) <strong class="caret glyphicon glyphicon-triangle-bottom"></strong>';

                $('#totalCartPrice').html('<h3>Total: £' + updatedCart.cartPrice + '</h3>');

                document.getElementById("CartDropdownHolder").innerHTML = html;

            }

        });

    });
});

购物车控制器上的 UpdateAllCartItems 方法:

    public ActionResult  UpdateAllCartItems(string id, string qty)
    {
        CartItems = (List<CartItem>)Session["Cart"];

        foreach (var item in CartItems)
        {
            if (item.CartItemId == Convert.ToInt32(id))
            {
                item.CartItemQty = qty;
            }
        }

        CartItems = (List<CartItem>)Session["Cart"];

        string cartTotal = CalculateCartTotal(CartItems);

        Session["Cart"] = CartItems;

        return Json(new {cartItems = CartItems, cartPrice = cartTotal });    
    }

如果有人能告诉我如何解决这个令人沮丧的问题,我将不胜感激。

【问题讨论】:

  • 一种解决方案:您可以在 (document).ready 块中重新加载 ViewCartContents.cshtml 中的页面数据。让它对控制器上的操作执行 AJAX 调用,该操作返回页面的数据并在客户端填充它。
  • 我敢打赌,您的会话正在被其他地方的另一个控制器操作清除。
  • @garryp 感谢您的评论。我可以确认会话值是正确的。一旦页面重新加载|(通过按 F5),会话中的正确值就会显示
  • 确保从控制器传入更新的视图数据。仔细检查您的视图模型!

标签: c# ajax session model-view-controller session-state


【解决方案1】:

在任何时候,当您在浏览器中按下后退按钮时,浏览器都会加载缓存的页面。因此,您看到的只有 1 个数量的页面是缓存页面。您正在使用 javascript 在客户端更改数量,它不会被浏览器缓存。

这可以通过对加载页面的 MVC 操作使用 OutputCache 属性来克服。

一般 OutputCache 属性用于通过在浏览器中缓存页面来提高性能。它还可以用于控制浏览器完成的缓存。使用以下属性添加 OutputCache 属性,页面将不会被浏览器缓存,并且每次您在浏览器中单击返回按钮时,它都会向服务器发送一个新请求以获取具有最新信息的页面。

[OutputCache(Duration=0, VaryByParam="none", Location=OutputCacheLocation.Client, NoStore=true)]
public ActionResult Cart()
{
//your code goes here.
}

希望这会有所帮助。

谢谢, R.文卡特桑

【讨论】:

  • 非常感谢这确实符合我的要求。一个小时后我会奖励你的赏金
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-03
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2023-03-19
  • 2019-12-05
相关资源
最近更新 更多