0

I am building a shopping cart using ASP.NET (C#). I have the cart working in the code behind, but I have to implement it across several product pages, so I would like to move it to a class for maintainability, but I'm having trouble.

I am using a Dictionary to store the product ID and quantity desired, then I store that Dictionary into a Session variable to store the cart between postbacks and navigating the site. The Dictionary is a global variable in multiple pages' code-behind.

public partial class products : System.Web.UI.Page
{
    Dictionary<int, int> CartList; 

On Page_Load, I am checking if the Session variable has a value:

protected void Page_Load(object sender, EventArgs e)
{
    if (Session["CartList"] == null)
    {
        CartList = new Dictionary<int, int>();
        Session["CartList"] = CartList; 
    }
}

When an Add to Cart button is clicked I have the following event handler. The button passes the product ID to the event handler in an attribute that was assigned to it when it was dynamically created. Then we loop through the dictionary to see if that product is already in the cart, and if so, we update the quantity by 1, then store the updated dictonary into the session variable:

protected void btnAddProduct_Click(object sender, EventArgs e)
{
    Button btn = (Button)sender;

    int pId = Convert.ToInt32(btn.Attributes["data-id"]);

    CartList = (Dictionary<int, int>)Session["CartList"];

    int count = 1;

    if (pId  > 0)
    {
        if (CartList.Count > 0)
        {
            foreach (KeyValuePair<int, int> item in CartList)
            {
                if (item.Key == pId)
                {                         
                    count = item.Value + 1; 
                }
            }
        }

        if (count > 1)
        {
            CartList[pId] = count;
        }
        else
        {
            CartList.Add(pId, count);
        }
    }

    Session["CartList"] = CartList;              
}

On the Cart Display page, I have a global CartList Dictonary again:

public partial class cart : System.Web.UI.Page
{        

   Dictionary<int, int> CartList;

On Page_PreInit, I am checking if my session variable has a value, and if so, we display the cart:

protected void Page_PreInit(object sender, EventArgs e)
{

    if (Session["CartList"] != null)
    {
        CartList = (Dictionary<int, int>)Session["CartList"];
        DisplayCartList();

    }
    else
    {
        lbl = new Label();
        lbl.Text = "<h1>There are no items in your cart.</h1>";
        Master.FindControl("ContentPlaceHolder1").Controls.Add(lbl);
    }
 }

I've read that a session variable might not be the best approach for this, so any ideas in that regard are appreciated. I understand that using Cache may be better, but I'm not very familiar with it yet. Either way, I would like to have the Dictionary and Session or Cache variable inside a class that is accessible across the website.

I have read about using a Session Wrapper class such as this example: How to access session variables from any class in ASP.NET? to hold the session, but I can't seem to get my head wrapped around that idea.

2 Answers2

0

I kinda figured it out. Not exactly what I was looking for, but I was able to move the Add to Cart function to a class by passing the Dictionary to a static class.

 public static class Cart
 {
    public static string AddCartItem(this Dictionary<int, string[]> CartList, int pId)
    {
        products p = new products();     

        ProductOptions po = new ProductOptions(); 

        if (pId > 0)
        {
            p.GetDataById(pId); 
            po.GetDataByProductId(pId);
        }

        CartList = (Dictionary<int, string[]>)HttpContext.Current.Session["CartList"];

        int count = 1;


        if (p.ID > 0)
        {
            if (CartList.Count > 0)
            {
                foreach (KeyValuePair<int, string[]> item in CartList)
                {
                    if (item.Key == p.ID)
                    {
                        count = Convert.ToInt32(item.Value[0]) + 1;
                    }
                }
            }

            if (count > 1)
            {
                CartList[p.ID][0] = count.ToString();
            }
            else
            {
                string[] value = new string[] { count.ToString(), po.Options };
                CartList.Add(p.ID, value);
            }
        }

        HttpContext.Current.Session["CartList"] = CartList;

        return p.Name; 
    }


}

Note: I also changed the Dictionary from 'int, int' to 'int, string[]' so that I could send product options such as size, color, flavor, etc. to the shopping cart along with the quantity ordered - all paired with the product Id.

0

Session variables are very useful tools, but they have their drawbacks, so should be used judiciously.

The drawbacks mainly are:

  1. Takes up memory on the server. If one has many sessions vars and they store large data structures this can be costly especially if you have memory restriction and your target audience is large. (* This is less true in in ASP.net than in Classic ASP)

  2. Session variables can be modified from anywhere in the application so one has to keep track of the value at all times.

*The latter could actually be more tricky then it sounds, especially when you have a large and complex App like a Shopping-Cart.

For example: if you are displaying the shopping cart content in a control on your page on which you are modifying the contents of the shopping cart. If you are adding an item and posting back the control may load with (old) session values as the add to list function will occur after the control is built .

Hope this is helpful.

DaniDev
  • 2,471
  • 2
  • 22
  • 29