Monday, October 10, 2011

Shopping Cart Example Code In ASP.NET GridView DataList

Creating Shopping cart example source code using asp.net 2.0,3.5 with gridview and datalist C#.NET,VB.NET
In this example i'm using GridView and DataList controls to create Products page and Product Details page in online shopping cart example










First of all we need to create a ShoppingCart class, for this right click on solution explorer and add new class, name it ShoppingCart.cs
Write this code in ShoppingCart.cs class

namespace ShoppingCartExample
{
/// <summary>
/// Summary description for ShoppingCart
/// </summary>
[Serializable]
public class CartItem
{
private int _productID;
private string _productName;
private string _imageUrl;
private int _quantity;
private double _price;
private double _subTotal;

public CartItem()
{
}
public CartItem(int ProductID, string ProductName,
string ImageUrl, int Quantity, double Price)
{
_productID = ProductID;
_productName = ProductName;
_imageUrl = ImageUrl;
_quantity = Quantity;
_price = Price;
_subTotal = Quantity * Price;
}
public int ProductID
{
get
{
return _productID;
}
set
{
_productID = value;
}
}
public string ProductName
{
get { return _productName; }
set { _productName = value; }
}
public string ImageUrl
{
get { return _imageUrl; }
set { _imageUrl = value; }
}

public int Quantity
{
get { return _quantity; }
set { _quantity = value; }
}

public double Price
{
get { return _price; }
set { _price = value; }
}

public double SubTotal
{
get { return _quantity * _price; }

}
}
[Serializable]
public class Cart
{
private DateTime _dateCreated;
private DateTime _lastUpdate;
private List<CartItem> _items;

public Cart()
{
if (this._items == null)
{
this._items = new List<CartItem>();
this._dateCreated = DateTime.Now;
}
}

public List<CartItem> Items
{
get { return _items;}
set { _items = value;}
}

public void Insert(int ProductID, double Price,
int Quantity, string ProductName, string ImageUrl)
{
int ItemIndex = ItemIndexOfID(ProductID);
if (ItemIndex == -1)
{
CartItem NewItem = new CartItem();
NewItem.ProductID = ProductID;
NewItem.Quantity = Quantity;
NewItem.Price = Price;
NewItem.ProductName = ProductName;
NewItem.ImageUrl = ImageUrl;
_items.Add(NewItem);
}
else
{
_items[ItemIndex].Quantity += 1;
}
_lastUpdate = DateTime.Now;
}

public void Update(int RowID, int ProductID,
int Quantity, double Price)
{
CartItem Item = _items[RowID];
Item.ProductID = ProductID;
Item.Quantity = Quantity;
Item.Price = Price;
_lastUpdate = DateTime.Now;
}

public void DeleteItem(int rowID)
{
_items.RemoveAt(rowID);
_lastUpdate = DateTime.Now;
}

private int ItemIndexOfID(int ProductID)
{
int index = 0;
foreach (CartItem item in _items)
{
if (item.ProductID == ProductID)
{
return index;
}
index += 1;
}
return -1;
}

public double Total
{
get
{
double t = 0;
if (_items == null)
{
return 0;
}
foreach (CartItem Item in _items)
{
t += Item.SubTotal;
}
return t;
}
}

}
}

Now to create Products page, add a new webform and name it Products.aspx, add sqldataSource and configure it for select statement,
read this for how to configure SqlDataSource
Add a DataList Control on the page and make SqlDataSource1 it's source.
Configure Datalist according to below mentioned source
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [ProductID], [Name], [Description],
[Price], [ImageUrl] FROM [Products]"
>
</asp:SqlDataSource>
</div>

<asp:DataList ID="DataList1" runat="server"
DataSourceID="SqlDataSource1"
RepeatColumns="4"
RepeatDirection="Horizontal">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl='<%# Eval("ImageUrl", "Images\\thumb_{0}") %>'
PostBackUrl='<%# Eval("ProductID",
"ProductDetails.aspx?ProductID={0}") %>'
/>
<br />
<asp:Label ID="NameLabel" runat="server"
Text='<%# Eval("Name") %>'>
</asp:Label>
<asp:Label ID="PriceLabel" runat="server"
Text='<%# Eval("Price", "{0:C}") %>'>
</asp:Label><br />
<br />
<br />
</ItemTemplate>
</asp:DataList><br />
<asp:HyperLink ID="CartLink" runat="server"
NavigateUrl="~/UserCart.aspx">
View Shopping Cart
</asp:HyperLink><br />
</form>

Now add a new webform and name it ProductDetails.aspx , this page is used for showing details for selected product from product catalog page, again add a SqlDataSource and DataList Control on this page and configure them according to source shown below, this time datalist is populated using QueryString Parameters.
<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [ProductID], [Name], [Description],
[Price], [ImageUrl] FROM [Products]
WHERE ([ProductID] = @ProductID)"
>
<SelectParameters>
<asp:QueryStringParameter Name="ProductID"
QueryStringField="ProductID"
Type="Decimal" />
</SelectParameters>
</asp:SqlDataSource>
</div>

<asp:DataList ID="DataList1" runat="server"
DataSourceID="SqlDataSource1">
<ItemTemplate>
<asp:Image ID="Image1" runat="server"
ImageUrl='<%# Eval("ImageUrl","~/Images\\{0}") %>'/>
<asp:Label ID="ImageUrlLabel" runat="server"
Text='<%# Eval("ImageUrl") %>'
Visible="False">
</asp:Label><br />
<asp:Label ID="NameLabel" runat="server"
Text='<%# Eval("Name") %>'>
</asp:Label><br />
<asp:Label ID="DescriptionLabel" runat="server"
Text='<%# Eval("Description") %>'>
</asp:Label><br />
<asp:Label ID="PriceLabel" runat="server"
Text='<%# Eval("Price", "{0:##0.00}" ) %>'>
</asp:Label><br />
</ItemTemplate>
</asp:DataList><br />
<asp:Button ID="btnAdd" runat="server" OnClick="Button1_Click"
Text="Add to Cart" /><br /><br />
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/Products.aspx">
Return to Products Page
</asp:HyperLink>
Write this code in C# code behind of ProductDetails.aspx page
protected void Button1_Click(object sender, EventArgs e)
{
double Price = double.Parse(((Label)
DataList1.Controls[0].FindControl("PriceLabel")).Text);
string ProductName = ((Label)
DataList1.Controls[0].FindControl("NameLabel")).Text;
string ProductImageUrl = ((Label)
DataList1.Controls[0].FindControl("ImageUrlLabel")).Text;
int ProductID = int.Parse(Request.QueryString["ProductID"]);
if (Profile.SCart == null)
{
Profile.SCart = new ShoppingCartExample.Cart();
}
Profile.SCart.Insert
(ProductID, Price, 1, ProductName, ProductImageUrl);
Server.Transfer("Products.aspx");
}

Now right click on solution explorer and add new web user control, name it CartControl.ascx
In design view of this control add a new GridView control and a label below gridview, html shource of this control should look like this
<%@ Control Language="C#" AutoEventWireup="true" 
CodeFile="CartControl.ascx.cs"
Inherits="CartControl" %>

<asp:GridView ID="grdCart" runat="server"
AutoGenerateColumns="False"
DataKeyNames="ProductID"
OnRowCancelingEdit="grdCart_RowCancelingEdit"
OnRowDeleting="grdCart_RowDeleting"
OnRowEditing="grdCart_RowEditing"
OnRowUpdating="grdCart_RowUpdating">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="Image1" runat="server"
ImageUrl='<%#Eval("ImageUrl","~/Images/thumb_{0}")%>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductName"
HeaderText="Product" ReadOnly="True"/>
<asp:BoundField DataField="Quantity" HeaderText="Quantity"/>
<asp:BoundField DataField="Price" DataFormatString="{0:c}"
HeaderText="Price" ReadOnly="True" />
<asp:BoundField DataField="SubTotal" DataFormatString="{0:c}"
HeaderText="Total" ReadOnly="True" />
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True"/>
</Columns>
<EmptyDataTemplate>
Your Shopping Cart is empty, add items
<a href="Products.aspx">Add Products</a>
</EmptyDataTemplate>
</asp:GridView>
<asp:Label ID="TotalLabel" runat="server"></asp:Label>

Open web.config file and add this section for enabling anonymous users to add items to cart

<system.web>
<authorization>
<allow users="?" />
<allow roles="admin" />
</authorization>
<roleManager enabled="true" />
<authentication mode="Forms" />
<compilation debug="true">
</compilation>
</system.web>
<system.web>
<anonymousIdentification enabled="true"/>
<profile enabled="true">
<properties>
<add name="SCart" serializeAs="Binary"
type="ShoppingCartExample.Cart"
allowAnonymous="true"/>
</properties>
</profile>
</system.web>

Now go to code behnd of CartControl.ascx and write this code
protected void Page_Load(object sender, EventArgs e)
{
if (Profile.SCart == null)
{
Profile.SCart = new ShoppingCartExample.Cart();
}
if (!Page.IsPostBack)
{
ReBindGrid();
}
if(Profile.SCart.Items == null)
{
TotalLabel.Visible = false;
}
}
protected void grdCart_RowEditing
(object sender, GridViewEditEventArgs e)
{
grdCart.EditIndex = e.NewEditIndex;
ReBindGrid();
}
protected void grdCart_RowUpdating
(object sender, GridViewUpdateEventArgs e)
{
TextBox txtQuantity = (TextBox)
grdCart.Rows[e.RowIndex].Cells[2].Controls[0];
int Quantity = Convert.ToInt32(txtQuantity.Text);
if (Quantity == 0)
{
Profile.SCart.Items.RemoveAt(e.RowIndex);
}
else
{
Profile.SCart.Items[e.RowIndex].Quantity
= Quantity;
}
grdCart.EditIndex = -1;
ReBindGrid();
}
protected void grdCart_RowCancelingEdit
(object sender, GridViewCancelEditEventArgs e)
{
grdCart.EditIndex = -1;
ReBindGrid();
}
protected void grdCart_RowDeleting
(object sender, GridViewDeleteEventArgs e)
{
Profile.SCart.Items.RemoveAt(e.RowIndex);
ReBindGrid();
}
private void ReBindGrid()
{
grdCart.DataSource = Profile.SCart.Items;
DataBind();
TotalLabel.Text = string.Format("Total:{0,19:C}",
Profile.SCart.Total);
}

Now add Global Application Class (Global.asax) by right clicking on solution explorer > add new Item. and write code mentioned below in it.
01void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs e)
02    {
03        ProfileCommon anonymousProfile = Profile.GetProfile(e.AnonymousID);
04        if (anonymousProfile.SCart != null)
05        {
06            if (Profile.SCart == null)
07                Profile.SCart = new ShoppingCartExample.Cart();
08 
09            Profile.SCart.Items.AddRange(anonymousProfile.SCart.Items);
10 
11            anonymousProfile.SCart = null;
12        }
13 
14        ProfileManager.DeleteProfile(e.AnonymousID);
15        AnonymousIdentificationModule.ClearAnonymousIdentifier();
16    }
17 


Add another webform and name it UserCart.aspx, in design view of this page drag the CartControl we've just created and put a hyperlink for going back to products cataloge page

Tha's it , build and run the application
Have fun

Download the sample code attached