从ASP.NET中的会话状态还原表

时间:2015-10-24 06:29:48

标签: c# asp.net session-state

好吧,我猜这里有点瘦。我有一个小的购物车网络应用程序,我在ASP.NET和C#中一直在玩弄。它现在非常基本;它目前只有三页,这个过程基本上是挑选你的物品,挑选你想要的物品,然后将它/它们添加到你的购物车中。

前两页完美无缺 ...购物车是我遇到麻烦的地方。购物车页面的主旨是它动态地构建一个表格,其中包含有关所添加产品的相关信息。每当用户返回项目页面并选择其他产品时,应该将其添加到购物车桌面的最后一行。

我正在使用会话状态,以便在购物车页面的页面访问之间跟踪购物车。当我第一次启动页面并添加第一个项目时它完美运行,我得到了我应该在页面上看到的内容(见下面的截图):

Screenshot of first item added

不幸的是,从那里开始下山。尝试添加其他商品后,甚至只需点击“购物车”即可。查看购物车时的菜单链接所有输入的信息都消失了。 (顺便说一句,不知道它是否相关,但在向购物车添加任何内容之前点击“购物车”菜单链接并不会产生相同的行为。所以我&#39我们希望将其缩小到项目添加之后发生的事情。)

Screenshot of cart after simply clicking the 'Cart' menu link

这是我购物车的C#代码背后的代码块,负责将数据添加到页面上的表格。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class viewCart : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        if (Session["myTable"] != null)
        {
            tblCartItems = (Table)Session["myTable"];

            for (int i = 1; i < tblCartItems.Rows.Count; i++)
            {
                tblCartItems.Rows.Add(tblCartItems.Rows[i]);
            }
        }

        if (Request.QueryString["qty"] != null)
        {
            string item = Request.QueryString["item"];
            int qty = int.Parse(Request.QueryString["qty"]);
            double price = double.Parse(Request.QueryString["price"]);

            TableRow row = new TableRow();
            row.Cells.Add(addCell(item));
            row.Cells.Add(addCell(qty.ToString()));
            row.Cells.Add(addCell(price.ToString()));
            row.Cells.Add(addCell(extPrice(qty, price).ToString()));
            row.Cells.Add(addCell("<asp:Button ID=\"btn_RemoveRow\" runat=\"server\" Text=\"Remove Item\" />"));

            tblCartItems.Rows.Add(row);

            Session["myTable"] = tblCartItems;
        }  
    } 
}

初始表(这是一个标准的,简单的ASP.NET表,没有什么超级花哨的),如果你去购物车页面没有添加任何项目,你会看到的只是表头,这些都是用购物车的.aspx文件,不在后面的代码中。因此,背后的所有代码都是通过item.aspx页面(您选择了多少项目的页面)传递数据,并通过URL查询字符串将信息传递到购物车页面。我也在使用这个小应用程序的母版页(如果它完全相关的话)。

我喜欢95%确定我走在正确的轨道上而且我只是错过了一些愚蠢的小事。如果有人能指出我正确的方向,我会非常感激,因为这一直让我疯狂!

2 个答案:

答案 0 :(得分:2)

您似乎已为网页上的表格以及您退出会话状态的变量选择了相同的变量名称。

因此,在首次加载会话[&#34; myTable&#34;]为空时,您将进入第二个块,构造HTML表并将其存储到会话状态。然后在第二次加载时,从会话状态中拉出HTML表,并尝试覆盖页面本身上的表(然后将会话对象中的行复制到自身)。

    if (Session["myTable"] != null)
    {
        Table tblCartItemsSession = (Table)Session["myTable"];

        for (int i = 1; i < tblCartItemsSession.Rows.Count; i++)
        {
            tblCartItems.Rows.Add(tblCartItemsSession.Rows[i]);
        }
    }

我认为上述改变应该有效,但我还没有对其进行测试。

此外,存储HTML对象不是最佳做法,您应该创建一个Cart对象,然后编写一些转换逻辑来显示Cart对象中的表,这里有一个示例来帮助有这个。

首先,虚拟对象:

public class CartItem 
{
    public string item { get; set; }
    public int qty { get; set; }
    public double price { get; set; }
}

然后顶部变为:

List<CartItem> items = new List<CartItem>();
if (Session["myCart"] != null)
{
    Items = (List<CartItem>)Session["myCart"];
}

然后,使用新对象(由查询字符串变量构成)

添加到列表中
items.Add(new CartItem() {
   item = item,
   qty = qty,
   price = price
});

然后,显示项目列表,我建议使用网格视图,它只是让它更容易(参见:http://www.c-sharpcorner.com/UploadFile/7eb164/gridview-control-in-Asp-Net/),最后将项目列表保存到您的会话变量

答案 1 :(得分:-2)

这可能对原始海报没有帮助,但可能会帮助其他人。我处于完全相同的位置,有一个截止日期,以及subpar c#知识,所以我使用了很好的老技巧:我在我的数据库中创建了一个购物车表,并将其绑定到网页中的gridview,并使用正确的控件添加,清除,重置等。

这可能不是最好的解决方案,但它确实帮助了我。