Bài viết mới:

Thứ Hai, 24 tháng 4, 2017

Tạo giỏ hàng trực tuyến trong ASP.NET WebForm

Bài viết này hướng dẫn cách để tạo 1 giỏ hàng trực tuyến trong ASP.NET WebForm bằng cách sử dụng Session.

Hình minh họa

1. Tạo class CardItem


Đầu tiên chúng ta cần tạo 1 class đại diện cho các item trong giỏ hàng, mình sẽ đặt tên class này là CardItem. Nội dung trong class này gồm các thuộc tính như sau:

    public class CartItem
    {
        public int MaSanPham { get; set; }
        public string TenSanPham { get; set; }
        public int SoLuong { get; set; }
        public int DonGia { get; set; }
        public string Hinh { get; set; }
        public int ThanhTien
        {
            get
            {
                return SoLuong * DonGia;
            }
        }
    }

Đây đều là những thuộc tính cần thiết để hiển thị ở trang giò hảng giống như hình minh họa bên trên. Cũng lưu ý rằng vì table Product ở CSDL của mình lưu mã sản phẩm là kiểu int tự tăng nên mình tạo thuộc tính MaSanPham kiểu int, có thể bạn lưu ở kiểu dữ liệu khác thì hãy tự sửa cho đúng nhé.

2. Tạo nút "Đặt vào giỏ"


Bạn có thể đặt nút này ở bất cứ đâu mà bạn cho rằng hợp lý. Ở ví dụ này mình đặt nút này ở trang chi tiết sản phẩm.

Đây là tag html của nút: 
<a href="/AddProductToCart.aspx?id=<%#: Item.MaSanPham %>">
Mua ngay
</a>

Bạn có thể dễ dàng thấy rằng đây là 1 tag anchor chứa 1 attribute href để gọi đến file AddProductToCart.aspx (chúng ta sẽ tạo file này bên dưới) và truyển thêm 1 querystring có tên là id với giá trị là mã sản phẩm của sản phẩm đang hiển thị ở trang chi tiết.

3. Tạo file AddProductToCart.aspx


Bạn mở code behind của file này và thay thế lệnh bên trong thành như sau:

        public partial class AddProductToCart : System.Web.UI.Page
       {
        public List<CartItem> MyShoppingCart
        {
            get
            {
                return Session["shoppingcart"] as List<CartItem>;
            }
            set
            {
                Session["shoppingcart"] = value;
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["id"] == null)
            {
                return;
            }
            if(HttpContext.Current.Session["shoppingcart"] == null)
            {
                Session.Add("shoppingcart",new List<CartItem>());
            }
            int maSanPham = int.Parse(Request.QueryString["id"]);
            CartItem newItem = MyShoppingCart.FirstOrDefault(m => m.MaSanPham == maSanPham);
            if(newItem != null)
            {
                newItem.SoLuong++;
            }
            else
            {
                ShopAroundEntities db = new ShopAroundEntities();
                SanPham sanPham = db.SanPhams.Find(maSanPham);
                newItem = new CartItem()
                {
                    MaSanPham = maSanPham,
                    TenSanPham = sanPham.TenSanPham,
                    DonGia = sanPham.DonGia,
                    Hinh = sanPham.Hinh,
                    SoLuong = 1
                };
                MyShoppingCart.Add(newItem);
            }
            
            Response.Redirect("ShoppingCart.aspx");
            
        }
    }


- Thuộc tính MyShoppingCart để lấy ra danh sách sản phẩm giỏ hàng thông qua biến Session["shoppingcart"] có kiểu dữ liệu là 1 List<CardItem>

- Ở event Page_Load() mình kiểm tra xem có querystring id được truyền qua webform không. Nếu không có thì return mà không làm gì thêm.

- Lệnh  if(HttpContext.Current.Session["shoppingcart"] == null) kiểm tra xem đã tồn tại Session["shoppingcart"] chưa. Nếu chưa thì chúng ta sẽ tạo ra Session["shoppingcart"] thông qua lệnh Session.Add("shoppingcart",new List<CartItem>()); 

- Lệnh int maSanPham = int.Parse(Request.QueryString["id"]); để tạo ra biến maSanPham với giá trị từ querystring id truyền qua.

- Lệnh CartItem newItem = MyShoppingCart.FirstOrDefault(m => m.MaSanPham == maSanPham); tìm 1 CardItem dựa theo giá trị của maSanPham. Nếu bạn rành về LINQ thì không xa lạ đoạn lệnh này. Nhớ rằng MyShoppingCart được lấy ra từ thuộc tính ta đã tạo ở trên.

- Tiếp theo là đoạn if else kiểm tra xem đối tượng newItem có tồn tại không. Nếu đã tồn tại tức là sản phẩm này đã có trong giỏ hàng thì chúng ta không thêm vào giỏ hàng nữa mà chỉ tăng số lượng lên, ngược lại thì chúng ta sẽ thêm sản phẩm này vào giỏ hàng thông qua đoạn lệnh trong khối else:


ShopAroundEntities db = new ShopAroundEntities();
                SanPham sanPham = db.SanPhams.Find(maSanPham);
                newItem = new CartItem()
                {
                    MaSanPham = maSanPham,
                    TenSanPham = sanPham.TenSanPham,
                    DonGia = sanPham.DonGia,
                    Hinh = sanPham.Hinh,
                    SoLuong = 1
                };
                MyShoppingCart.Add(newItem);



- Mình đang demo sử dụng công nghệ Entity Framework Database First nên đoạn lệnh tìm sản phẩm trong CSDL sẽ như trên (thông qua method Find trong DbSet<SanPhams>). Sau khi lấy ra sanPham từ CSDL thành công thì mình thực hiện khởi tạo đối tượng newItem và gán các thuộc tính của newitem thành các giá trị thích hợp từ đối tượng sanPham.

- Sau đó mình dùng lệnh MyShoppingCart.Add(newItem); để thêm đối tượng newItem vào giỏ hàng.

- Cuối cùng là lệnh Response.Redirect("ShoppingCart.aspx"); để chuyển hướng sang trang giỏ hàng. File ShoppingCart.aspx chúng ta sẽ sớm tạo bên dưới.

4. Tạo file ShoppingCart.aspx


Đây là file webform để hiển thị giỏ hàng trực tuyến. Bạn dán đoạn lệnh bên dưới bổ sung vào phần ContentPlaceHolder của trang:

  <% if (Session["shoppingcart"] == null || ((List<ShopAround.Models.CartItem>)Session["shoppingcart"]).Count == 0)
        { %>
    <p>
        Giỏ hàng rỗng
    </p>
    <% } %>
    <% else { %>
    <table style="width:100%;">
        <thead>
            <tr>
                <th>Hình</th>
                <th>Tên sản phẩm</th>
                <th>Đơn giá</th>
                <th>Số lượng</th>
                <th>Thành tiền</th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
           
        </thead>
       <% foreach (var cardItem in Session["shoppingcart"] as List<ShopAround.Models.CartItem>) { %>
        <tr>
            <td><img src="/Photos/Products/<%= cardItem.Hinh %>" width="70" height="70" /></td>
            <td> <%= cardItem.TenSanPham %></td>
            <td> <%= cardItem.DonGia.ToString("#,##0") %> đ</td>
            <td> <%= cardItem.SoLuong %></td>
            <td> <%= cardItem.ThanhTien.ToString("#,##0") %> đ</td>
            <td> <a title="Tăng số lượng" href="/EditCartItem.aspx?id=<%= cardItem.MaSanPham %>&change=plus" style="text-decoration:none" class="btn btn-default" ><span class="fa fa-plus"></span></a></td>
            <td> <a title="Giảm số lượng" href="/EditCartItem.aspx?id=<%= cardItem.MaSanPham %>&change=minus" style="text-decoration:none" class="btn btn-default" ><span class="fa fa-minus"></span></a></td>
            <td> <a onclick="return confirm('Bạn có chắc muốn bỏ sản phẩm này khỏi giỏ hàng?');" href="DeleteCartItem?id=<%= cardItem.MaSanPham %>" style="text-decoration:none" class="btn btn-default" ><span class="fa fa-trash-o"></span> Xóa</a></td>
        </tr>
        <% } %>
        <tr>
            <td></td>
            <td></td>
            <td> Tổng số lượng: </td>
            <td> <%= ((List<ShopAround.Models.CartItem>)Session["shoppingcart"]).Sum(m => m.SoLuong) %> sản phẩm</td>
            <td> Tổng thành tiền: </td>
            <td> <%= ((List<ShopAround.Models.CartItem>)Session["shoppingcart"]).Sum(m => m.ThanhTien).ToString("#,##0") %> đồng</td>
            <td></td>
            <td></td>
        </tr>
    </table>
    <% } %> 


Nội dung ở trang giỏ hàng hiển thị danh sách các sản phẩm người dùng đặt vào giỏ, tổng số lượng, tổng thành tiền bằng tag table. Ngoài ra mỗi 1 dòng ở table còn đi kèm 3 button "Tăng số lượng", "Giảm số lượng", "Xóa". Mỗi button thực ra là mỗi tag a chứa href link đến các file EditCartItem.aspxDeleteCardItem.aspx kèm theo các querystring cần thiết để xử lý.

Trong trường hợp giỏ hàng chưa được khởi tạo hoặc rỗng thì trang sẽ hiển thị dòng chữ "Giỏ hàng rỗng"

4. Tạo file EditCartItem.aspx


File này có chức năng sửa số lượng 1 item bất kỳ trong giỏ hàng. Dưới đây là nội dung code behind của file:

protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["shoppingcart"] != null && Request.QueryString["id"] != null && Request.QueryString["change"] != null)
            {
                int maSanPham;
                if(int.TryParse(Request.QueryString["id"].ToString(), out maSanPham))
                {
                    List<CartItem> shopppingCart = Session["shoppingcart"] as List<CartItem>;
                    CartItem cardItemEdit = shopppingCart.Single(m => m.MaSanPham == maSanPham);
                    if(Request.QueryString["change"] == "plus")
                    {
                        cardItemEdit.SoLuong++;
                    }
                    else if(Request.QueryString["change"] == "minus")
                    {
                        if(cardItemEdit.SoLuong > 1)
                        {
                            cardItemEdit.SoLuong--;
                        }
                        
                    }
                }
            }
                Response.Redirect("ShoppingCart.aspx");
        }

Đoạn lệnh lấy ra giá trị id được truyền thông qua querystring id và change. Trong đó giá trị id chính là giá trị mã sản phẩm của item muốn sửa. 

Chúng ta thực hiện tìm item này trong giỏ hàng thông qua method Single. Sau đó kiểm tra giá trị querystring change là "plus" hay "minus", nếu là "plus" thì ta thực hiện tăng số lượng của item ngược lại thì giảm số lượng. 

Cuối cùng redirect về lại trang giỏ hàng thông qua lệnh Response.Redirect("ShoppingCart.aspx");

5. Tạo file DeleteCartItem.aspx


File này có chức năng xóa 1 item bất kỳ trong giỏ hàng. Dưới đây là nội dung code behind của file:

protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["shoppingcart"] != null && Request.QueryString["id"] != null)
            {
                int maSanPham;
                if (int.TryParse(Request.QueryString["id"].ToString(), out maSanPham))
                {
                    List<CartItem> shopppingCart = Session["shoppingcart"] as List<CartItem>;
                    CartItem cardItem = shopppingCart.Single(m => m.MaSanPham == maSanPham);
                    shopppingCart.Remove(cardItem);
                    Response.Redirect("ShoppingCart.aspx");
                }
            }
            Response.Redirect("ShoppingCart.aspx");
        }

Lệnh ở file DeleteCartItem.aspx thực sự rất đơn giản. Lấy ra maSanPham của item thông qua querystring id từ tham số. Sau đó tìm item người dùng muốn xóa trong giỏ hàng thông qua method Single() và xóa item này khỏi giỏ hàng thông qua lệnh shopppingCart.Remove(cardItem);

Cuối cùng redirect về lại trang giỏ hàng thông qua lệnh Response.Redirect("ShoppingCart.aspx");

Vậy là xong 5 bước để có thể tạo được 1 giỏ hàng trực tuyến đầy đủ chức năng cần thiết trong ASP.NET. Chúc bạn thực hành thành công.