Shopping Cart in ASP.NET

Build a Shopping Cart in ASP.NET

Shopping carts are very important and can many times be the most intimidating part of building an e-commerce site. This tutorial will show how easy it can be to implement a shopping cart using ASP.NET. Additionally, several basic explanations will be provided to help beginning ASP.NET programmers understand this wonderful framework.

Quick Overview of ASP.NET

Since ASP.NET hasn’t been covered too much on NETTUTS, I thought it would be good to include a brief overview of some of the things that distinguish it from other languages.

  1. Code is compiled. The first time an ASP.NET page is requested over the web, the code is compiled into one or more DLL files on the server. This gives you the ability to just copy code out to the server and it gives you the speed benefit of compiled code.
  2. ASP.NET is an object oriented framework. Every function, property and page is part of a class. For example, each web page is its own class that extends the Page class. The Page class has an event that is fired when the webpage is loaded called the “Page Load Event”. You can write a function that subscribes to that event and is called on. The same principle applies to other events like the button click and “drop-down” “selected index changed” events.
  3. The logic is separate from the design and content. They interact with each other, but they are in separate places. Generally, this allows a designer to design without worrying about function and it allows the programmer to focus on function without looking at the design. You have the choice of putting them both in the same file or in different files. This is similar to model-view-controller model.

If you are new to ASP.NET (and you have Windows), you can try it out for free You can download Visual Studio Express by visiting the ASP.NET website. Also, when you create a website locally on your machine, you can run the website at any time and Visual Studio will quickly start a server on your computer and pull up your website in your default browser.

Step 1: Create the ShoppingCart Class

We need a place to store the items in the shopping cart as well as functions to manipulate the items. We’ll create a ShoppingCart class for this. This class will also manage session storage.

First, we have to create the App_Code folder. To do this, go to the “Website” menu, then “Add ASP.NET Folder”, and choose “App_Code.” This is where we’ll put all of our custom classes. These classes will automatically be accessible from the code in any of our pages (we don’t need to reference it using something similar to “include” or anything). Then we can add a class to that folder by right-clicking on the folder and choosing “Add New Item.”

Quick Tip: Regions in ASP.NET are really nice to organize and group code together. The nicest thing about them is that you can open and close regions to minimize the amount of code that you are looking at or quickly find your way around a file.

using System.Collections.Generic;
using System.Web;

/**
 * The ShoppingCart class
 * 
 * Holds the items that are in the cart and provides methods for their manipulation
 */
public class ShoppingCart {
    #region Properties
    
    public List<CartItem> Items { get; private set; }
    
    #endregion

    #region Singleton Implementation
    // Readonly properties can only be set in initialization or in a constructor
    public static readonly ShoppingCart Instance;

    // The static constructor is called as soon as the class is loaded into memory
    static ShoppingCart() {
        // If the cart is not in the session, create one and put it there
        // Otherwise, get it from the session
        if (HttpContext.Current.Session["ASPNETShoppingCart"] == null) {
            Instance = new ShoppingCart();
            Instance.Items = new List<CartItem>();
            HttpContext.Current.Session["ASPNETShoppingCart"] = Instance;
        } else {
            Instance = (ShoppingCart)HttpContext.Current.Session["ASPNETShoppingCart"];
        }
    }

    // A protected constructor ensures that an object can't be created from outside
    protected ShoppingCart() { }

    #endregion

    #region Item Modification Methods
    /**
     * AddItem() - Adds an item to the shopping 
     */
    public void AddItem(int productId) {
        // Create a new item to add to the cart
        CartItem newItem = new CartItem(productId);

        // If this item already exists in our list of items, increase the quantity
        // Otherwise, add the new item to the list
        if (Items.Contains(newItem)) {
            foreach (CartItem item in Items) {
                if (item.Equals(newItem)) {
                    item.Quantity++;
                    return;
                }
            }
        } else {
            newItem.Quantity = 1;
            Items.Add(newItem);
        }
    }

    /**
     * SetItemQuantity() - Changes the quantity of an item in the cart
     */
    public void SetItemQuantity(int productId, int quantity) {
        // If we are setting the quantity to 0, remove the item entirely
        if (quantity == 0) {
            RemoveItem(productId);
            return;
        }

        // Find the item and update the quantity
        CartItem updatedItem = new CartItem(productId);

        foreach (CartItem item in Items) {
            if (item.Equals(updatedItem)) {
                item.Quantity = quantity;
                return;
            }
        }
    }

    /**
     * RemoveItem() - Removes an item from the shopping cart
     */
    public void RemoveItem(int productId) {
        CartItem removedItem = new CartItem(productId);
        Items.Remove(removedItem);
    }
    #endregion

    #region Reporting Methods
    /**
     * GetSubTotal() - returns the total price of all of the items
     *                 before tax, shipping, etc.
     */
    public decimal GetSubTotal() {
        decimal subTotal = 0;
        foreach (CartItem item in Items)
            subTotal += item.TotalPrice;

        return subTotal;
    }
    #endregion
}

Step 2: The CartItem & Product Classes

With a place to store our shopping cart items, we need to be able to store information about each item. We’ll create a CartItem class that will do this. We’ll also create a simple Product class that will simulate a way to grab data about the products we’re selling.

The CartItem class:

using System;

/**
 * The CartItem Class
 * 
 * Basically a structure for holding item data
 */
public class CartItem : IEquatable<CartItem> {
    #region Properties

    // A place to store the quantity in the cart
    // This property has an implicit getter and setter.
    public int Quantity { get; set; }

    private int _productId;
    public int ProductId {
        get { return _productId; }
        set {
            // To ensure that the Prod object will be re-created
            _product = null;
            _productId = value;
        }
    }

    private Product _product = null;
    public Product Prod {
        get {
            // Lazy initialization - the object won't be created until it is needed
            if (_product == null) {
                _product = new Product(ProductId);
            }
            return _product;
        }
    }

    public string Description {
        get { return Prod.Description; }
    }

    public decimal UnitPrice {
        get { return Prod.Price; }
    }

    public decimal TotalPrice {
        get { return UnitPrice * Quantity; }
    }

    #endregion

    // CartItem constructor just needs a productId
    public CartItem(int productId) {
        this.ProductId = productId;
    }

    /**
     * Equals() - Needed to implement the IEquatable interface
     *    Tests whether or not this item is equal to the parameter
     *    This method is called by the Contains() method in the List class
     *    We used this Contains() method in the ShoppingCart AddItem() method
     */
    public bool Equals(CartItem item) {
        return item.ProductId == this.ProductId;
    }
}

The Product class:

/**
 * The Product class
 * 
 * This is just to simulate some way of accessing data about  our products
 */
public class Product
{

    public int Id { get; set; }
    public decimal Price { get; set; }
    public string Description { get; set; }

    public Product(int id)
    {
        this.Id = id;
        switch (id) {
            case 1:
                this.Price = 19.95m;
                this.Description = "Shoes";
                break;
            case 2:
                this.Price = 9.95m;
                this.Description = "Shirt";
                break;
            case 3:
                this.Price = 14.95m;
                this.Description = "Pants";
                break;
        }
    }

}

Definition: A “property” in ASP.NET is a variable in a class that has a setter, a getter, or both. This is similar to other languages, but in ASP.NET, the word property refers specifically to this. An example of this is the ProductId property in the CartItem class. It is not simply a variable in a class with a method to get or set it. It is declared in a special way with get{} and set{} blocks.

Let’s Add Items to the Cart

After having our heads in the code for so long, it’s time we do something visual. This page will simply be a way to add items to the cart. All we need is a few items with “Add to Cart” links. Let’s put this code in the Default.aspx page.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>My Store</title>
    <link href="Styles/StyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>

    <form id="form1" runat="server">
        
        <div class="container">
            <h1>My Store</h1>
            
            <div class="products">
                <div>Shoes - <asp:LinkButton runat="server" ID="btnAddShirt" OnClick="btnAddShoes_Click">Add To Cart</asp:LinkButton></div>

                <div>Shirt - <asp:LinkButton runat="server" ID="btnAddShorts" OnClick="btnAddShirt_Click">Add To Cart</asp:LinkButton></div>
                <div>Pants - <asp:LinkButton runat="server" ID="btnAddShoes" OnClick="btnAddPants_Click">Add To Cart</asp:LinkButton></div>
            </div>

            
            <a href="ViewCart.aspx">View Cart</a>
        </div>
        
    </form>
</body>
</html>

As you can see, the only thing happening here is that we have a few LinkButtons that have OnClick event handlers associated to them.

In the code-behind page, we have 4 event handlers. We have one for each LinkButton that just adds an item to the shopping cart and redirects the user to view their cart. We also have a Page_Load event handler which is created by the IDE by default that we didn’t need to use.

using System;

public partial class _Default : System.Web.UI.Page {
    protected void Page_Load(object sender, EventArgs e) {

    }

    protected void btnAddShoes_Click(object sender, EventArgs e) {
        // Add product 1 to the shopping cart
        ShoppingCart.Instance.AddItem(1);

        // Redirect the user to view their shopping cart
        Response.Redirect("ViewCart.aspx");
    }

    protected void btnAddShirt_Click(object sender, EventArgs e) {
        ShoppingCart.Instance.AddItem(2);
        Response.Redirect("ViewCart.aspx");
    }

    protected void btnAddPants_Click(object sender, EventArgs e) {
        ShoppingCart.Instance.AddItem(3);
        Response.Redirect("ViewCart.aspx");
    }

}

Build the Shopping Cart Page

Finally, what we’ve been preparing for the whole time—the shopping cart! Let’s just look at ViewCart.aspx first and I’ll explain it after that.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ViewCart.aspx.cs" Inherits="ViewCart" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Shopping Cart</title>
    <link href="Styles/StyleSheet.css" rel="stylesheet" type="text/css" />
</head>
<body>

    <form id="form1" runat="server">
        <div class="container">
            <h1>Shopping Cart</h1>
            <a href="Default.aspx">< Back to Products</a>

            <br /><br />
            <asp:GridView runat="server" ID="gvShoppingCart" AutoGenerateColumns="false" EmptyDataText="There is nothing in your shopping cart." GridLines="None" Width="100%" CellPadding="5" ShowFooter="true" DataKeyNames="ProductId" OnRowDataBound="gvShoppingCart_RowDataBound" OnRowCommand="gvShoppingCart_RowCommand">
                <HeaderStyle HorizontalAlign="Left" BackColor="#3D7169" ForeColor="#FFFFFF" />
                <FooterStyle HorizontalAlign="Right" BackColor="#6C6B66" ForeColor="#FFFFFF" />
                <AlternatingRowStyle BackColor="#F8F8F8" />
                <Columns>

                    <asp:BoundField DataField="Description" HeaderText="Description" />
                    <asp:TemplateField HeaderText="Quantity">
                        <ItemTemplate>
                            <asp:TextBox runat="server" ID="txtQuantity" Columns="5" Text='<%# Eval("Quantity") %>'></asp:TextBox><br />
                            <asp:LinkButton runat="server" ID="btnRemove" Text="Remove" CommandName="Remove" CommandArgument='<%# Eval("ProductId") %>' style="font-size:12px;"></asp:LinkButton>

                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:BoundField DataField="UnitPrice" HeaderText="Price" ItemStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Right" DataFormatString="{0:C}" />
                    <asp:BoundField DataField="TotalPrice" HeaderText="Total" ItemStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Right" DataFormatString="{0:C}" />
                </Columns>
            </asp:GridView>

            <br />
            <asp:Button runat="server" ID="btnUpdateCart" Text="Update Cart" OnClick="btnUpdateCart_Click" />
        </div>
    </form>
</body>
</html>

The GridView control is a powerful control that can seem complicated at first. I won’t discuss the style elements because they are self-explanatory. (There are some principles here that I’m not going to explain in depth. I am just going to try to get the main idea across). Let’s break it down.

  • Giving the GridView an ID will allow us to access the GridView from the code-behind using that ID.

    ID="gvShoppingCart"
  • The GridView will automatically generate columns and column names from the data that we supply unless we specifically tell it not to.

    AutoGenerateColumns="false"
  • We can tell the GridView what to display in case we supply it with no data.

    EmptyDataText="There is nothing in your shopping cart."
  • We want to show the footer so that we can display the total price.

    ShowFooter="true"
  • It will be nice for us to have an array of ProductIds indexed by the row index when we are updating the quantity of a cart item in the code-behind. This will do that for us:

    DataKeyNames="ProductId"
  • We need events to respond to two events: RowDataBound and RowCommand. Basically, RowDataBound is fired when the GridView takes a row of our data and adds it to the table. We are only using this event to respond to the footer being bound so that we can customize what we want displayed there. RowCommand is fired when a link or a button is clicked from inside the GridView. In this case, it is the “Remove” link.

    OnRowDataBound="gvShoppingCart_RowDataBound" OnRowCommand="gvShoppingCart_RowCommand"

Now let’s talk about the columns. We define the columns here and the GridView will take every row in the data that we supply and map the data in that row to the column that it should display in. The simplest column is the BoundField. In our case, it is going to look for a “Description” property in our CartItem object and display it in the first column. The header for that column will also display “Description.”

We needed the quantity to display inside a textbox rather than just displaying as text, so we used a TemplateField. The TemplateField allows you to put whatever you want in that column. If you need some data from the row, you just insert <%# Eval(“PropertyName”) %>. The LinkButton that we put in our TemplateField has a CommandName and a CommandArgument, both of which will be passed to our GridView’s RowCommand event handler.

The last thing worth mentioning here is that the last two BoundFields have a DataFormatString specified. This is just one of the many format strings that ASP.NET provides. This one formats the number as a currency. See the Microsoft documentation for other format strings.

Now we can look at the code-behind page. I have supplied lots of comments here to describe what is happening.

The End Result:

Now we have a nice working shopping cart!

You Also Might Like…

Screencast

How to Search a Website Using ASP.NET 3.5 – screencast

Oct 1st in Screencasts by Jeffrey Way

I’m happy to say that today, we are posting our very first article on ASP.NET. In this screencast, I’ll show you how to implement a simple search functionality into your personal website. We’ll go over many of the new features in ASP.NET 3.5, such as LINQ and many of the AJAX controls that ship with Visual Studio/Web Developer.

Continue Reading

  • Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.


Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.usetriad.com triad1984

    I don’t think anyone wants to post a database solution for this cart becuase custom shopping carts are pretty big business and if we share it here everyone will run off and create turn key solutions off this one guy’s code and I’m sure no one here has the decency to offer royalties to the author. So, since the database piece is really the meat and potatoes of an online cart I would think it’s safe to say no one’s going to provide the code.

  • http://www.stam@bk.ru Stam

    Hi. Can anybody post ShiopCart.cs&? Thnx

  • Bbaale

    Thank you very much,God bless your family

  • http://www.neotenyservicedesign.com.au/ Neoteny

    You have given a clear idea and specific direction for database which is going to help almost everyone. Thanks for sharing such an informative post. Nice information, many thanks to the author. It is incomprehensible to me now. You did a great job and your article is very informative.

  • masoud

    tanx for information

  • Arun

    How do i make it to use with different users.
    All users are having the same cart

  • Arun

    Please tell me how to create new cart rather than using same cart for all the users.

  • Bbaale Emmy

    Please tell me how to send the data in the shopping cart to an email address. Help please am doing a project and handing in 2 days from now. Notify me please via email. Ma Email is bbaale.emmy@gmail.com

  • JOhn

    Hello…
    Nice tutorial…but u have it in VB language?

  • http://net.tutsplus.com/tutorials/other/build-a-shopping-cart-in-aspnet/ David

    Need an tutorial for visual Studio asp.net and Visual Basic.

  • Rina

    Thank you…

  • julii

    anyone knows how to build payment method or shopping cart to sell service not products

  • atif

    nice tutorial

  • https://www.distance-course.com gaurav

    Hi,
    I have some problem with using this code , problem is that we click add to cart and we show all previous list and other user add item in the list and we can see what is solution i don’t plz help me

    How to create new user list for new user (new browser page)

    Give Me Soon Reply

    Thanks And Regards

    Gaurav Singh

  • Rina

    Hi, Urgently need help me with this error ->

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

    namespace princezz_shop
    {
    public partial class _Default : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void btnAddOBF_Click(object sender, EventArgs e)
    {
    ShoppingCart.Instance.AddItem(1);
    Response.Redirect(“ViewCart.aspx”);
    }

    protected void btnAddWCF_Click(object sender, EventArgs e) {
    ShoppingCart.Instance.AddItem(2);
    Response.Redirect(“ViewCart.aspx”);
    }

    protected void btnAddSC_Click(object sender, EventArgs e) {
    ShoppingCart.Instance.AddItem(3);
    Response.Redirect(“ViewCart.aspx”);
    }

    }
    }

    The ERR lies on the “ShoppingCart” from the .Instance…”. It’s UNDEFINED.

  • http://www.mikerowleyconstructions.com.au/ Jacob from asphalt melbourne

    I think this post is very important to everyone who do there best strategies to blast there shopping cart. Great post! Maybe you could do a follow up on this topic?

  • jorame

    How can you do this but instead of creating your own products manually, pulling them from a SQL Database?

  • Drone8

    This code works fine when testing it on my local machine, but when I test it on a Windows Server 2003 machine running IIS 6, I can no longer update the quantity of items in the shopping cart or remove items, and trying to add an item that is already in the cart also does not update the quantity. Any ideas why this is happening?

  • http://go2print.co.in raghavendra

    PLEAS SEND ME STEP BY STEP TOTAL ASP.NET E COMMERCE SHOPPING CART TUTORIALS
    PLEAS PLEAS

  • ccbl

    To any beginners – be careful using this code – you have to modify it so the shopping cart is not shared by all users!!!

    • newbi

      Can you elaborate on what needs to be changed? I have an issue where when items are added to the cart by multiple users we all see the same products in the cart. Any help would be appreciated.

  • http://www.maquinariamadrid.com/f_liquidacion_336.html compra venta de maquinaria

    Awesome issues here. I’m very satisfied to see your article. Thank you a lot and I am looking ahead to contact you. Will you kindly drop me a mail?

  • Pingback: pldtechs WordPress » Build a Shopping Cart in ASP.NET

  • http://www.eventoscrisal.com/empresas_de_eventos_en_madrid.ws Empresas eventos MAdrid

    Its such as you read my mind! You appear to know so much approximately this, like you wrote the e book in it or something. I believe that you simply could do with a few % to drive the message house a little bit, however instead of that, this is wonderful blog. A fantastic read. I will definitely be back.

  • http://www.esfacilsisabescomo.es metodos para dejar de fumar

    That is really interesting, You’re an overly professional blogger. I have joined your rss feed and look ahead to searching for more of your wonderful post. Also, I have shared your website in my social networks

  • Gagan

    Thanks for giving me a start ..

  • siri

    Hi,

    There is NO CODE for ViewCart.aspx.cs which is ViewCart.aspx code behind. Can you please add code behind to ViewCart.aspx.

  • Pingback: ASP.NET Tutorials

  • Mehul

    Hi,

    There is NO CODE for ViewCart.aspx.cs which is ViewCart.aspx code behind. Can you please add code behind to ViewCart.aspx.

  • Mehul

    Hi,

    There is NO CODE for ViewCart.aspx.cs which is ViewCart.aspx code behind. Can you please add code behind to ViewCart.aspx. and now in add cart to coding in the website asp.net

  • Mehul

    Hi,

    There is NO CODE for ViewCart.aspx.cs which is ViewCart.aspx code behind. Can you please add code behind to ViewCart.aspx. and now in add cart to coding in the website asp.net

  • Mehul

    hi..

    In this sort coding for add to cart in this asp.net

  • Ali Asgar

    Hi Don

    Your article is nice and working fine except one thing. When I add item to the cart from my PC it will add to shopping cart but when I open the same from another PC, it shows me my cart item on another PC.

    It means instance remains same.

    Please help me out. It’s urgent

    Thanks

  • http://net.tutsplus.com/tutorials/other/build-a-shopping-cart-in-aspnet/ Saleem Khan

    Thank you for your article. It works superb and it is simple in logic and working.

  • Nitin kushwaha

    really very urgent..
    just wanted to know that if one thousand users are visiting my site and they are adding items in their shopping cart now what happens is that if 500 of them close their browsers and now their session have expired, now just wanted to know will the shopping cart object clear itself(with items details in it) on session expire or it will go on consuming memory of server

  • http://stackoverflow.com/questions/10250288/c-sharp-shopping-cart Saurabh

    Please go through this url to rectify previous list issue.

  • Saurabh Srivastava

    Useful link to solve Showing previous list of items

    http://stackoverflow.com/questions/10250288/c-sharp-shopping-cart

  • http://notyet bozzo

    nice, it’s nice and awesome to google it and search from the first lines what you looking for…
    keep it up!

  • stu

    No session, I get the some result in different browses

  • http://www.quartofrancesco.it francesco

    Great ! it’s an utility example … thank you

  • bob

    Hi,

    I’m an absolute beginner to asp.net and this tutorial is great. Thanks so much! I’m just messing around with the code and I was wondering, is there a way to just display all the items in the shopping cart by default, bypassing the “Products” page?

    Any advice would be greatly appreciated.

  • sachin

    Its truely a Good Eg

  • Pingback: Tạo giỏ hàng trong ASP.NET « Tạp chí Lập trình

  • gafar

    Thanks for your contribution!

  • Zakraket

    Very helpfull! However, as someone mentioned before, the codebehind of the shoppingcart isn’t there? Would like to see it as some things are not clear

  • http://www.facebook.com/mohammed.h.ismaile Mohammed Hassen Ismaile

    thanks

    Very helpful!!!!!!!!!!!!!!!!!!!

  • akh

    thanks, nice tutorial
    but I can’t seem to find the code behind for viewcart.aspx …

  • akh

    oops…
    sorry, it’s (viewcart.aspx.cs) in the attached download

  • ashish

    public static readonly ShoppingCart Instance; as declared as static all the users will get each other data. bad design.

    • Harpreet

      Hi Ashish,

      you are right, shopping cart is shared with all users…..can you plz suggest us the solution to over come this problem

      • Don Wilson

        I posted the fix for this 4 years ago, but I’ll repost it so that it is easier to see:

        Here is what you would do to remove the Sinlgeton implementation:

        Replace lines 20-34 in the Shopping Cart class above with this:

        // The static constructor is called as soon as the class is loaded into memory
        public static ShoppingCart GetShoppingCart() {
        // If the cart is not in the session, create one and put it there
        if (HttpContext.Current.Session["ASPNETShoppingCart"] == null) {
        ShoppingCart cart = new ShoppingCart();
        cart.Items = new List();
        HttpContext.Current.Session["ASPNETShoppingCart"] = cart;
        }

        return (ShoppingCart)HttpContext.Current.Session["ASPNETShoppingCart"];
        }

        Then, every time that you need to access it, replace this:

        ShoppingCart.Instance.AddItem(1);

        with this:

        ShoppingCart cart = ShoppingCart.getShoppingCart();
        cart.AddItem(1);

      • deik

        Don,

        I have tried to figure this out, the MSDN site was unhelpful. But I cannot figure out how to use
        HttpContext. And it has stopped me dead in my tracks.
        d

    • Mohsen

      You right, incorrect using of single tone pattern

  • Bob

    I don’t think you really learn something from this. It is not dynamic at all. and what people want to learn is how to use it with a database.