Thứ Sáu, 7 tháng 9, 2018

Xây dựng Shopping Cart với Session trong ASP.NET CORE MVC


Giỏ hàng trực tuyến

Tạo Project ASP.NET Core MVC 


Từ Visual Studio, chọn tạo ASP.NET Core Web Application project


Chọn Empty Template


Click OK để hoàn tất.




Thêm Các Tệp Hình Ảnh


Tạo thư mục images trong thư mục wwwroot. Sao chép các hình ảnh sử dụng trong project vào thư mục.

Bổ Sung Configurations


Mở file Startup.cs và thêm các lệnh cấu hình mới như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace LearnASPNETCoreMVCWithRealApps
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddSession();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSession();

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Demo}/{action=Index}/{id?}");
            });

        }
    }
}

Entities Class


Tạo thư mục tên Models. Trong thư mục này, tạo các class thực thể như bên dưới:

Product Entity

Tạo class Product.cs như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVCWithRealApps.Models
{
    public class Product
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public string Photo { get; set; }
    }
}


Item Entity

Tạo class Entity.cs như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVCWithRealApps.Models
{
    public class Item
    {
        public Product Product { get; set; }

        public int Quantity { get; set; }
    }
}

Tạo Session Helper


Tạo thư mục tên Helpers. Trong thư mục này, tạo class SessionHelper.cs như sau:

using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace LearnASPNETCoreMVCWithRealApps.Helpers
{
    public static class SessionHelper
    {
        public static void SetObjectAsJson(this ISession session, string key, object value)
        {
            session.SetString(key, JsonConvert.SerializeObject(value));
        }

        public static T GetObjectFromJson<T>(this ISession session, string key)
        {
            var value = session.GetString(key);
            return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
        }
    }
}

Tạo thư mục tên Controllers. Trong thư mục này bạn tạo các controllers sau:

ProductController


Tạo class ProductController.cs nội dung như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LearnASPNETCoreMVCWithRealApps.Models;
using Microsoft.AspNetCore.Mvc;

namespace LearnASPNETCoreMVCWithRealApps.Controllers
{
    [Route("product")]
    public class ProductController : Controller
    {
        [Route("")]
        [Route("index")]
        [Route("~/")]
        public IActionResult Index()
        {
            ProductModel productModel = new ProductModel();
            ViewBag.products = productModel.findAll();
            return View();
        }
    }
}

CartController


Tạo class CartController.cs nội dung như sau:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LearnASPNETCoreMVCWithRealApps.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using LearnASPNETCoreMVCWithRealApps.Helpers;

namespace LearnASPNETCoreMVCWithRealApps.Controllers
{
    [Route("cart")]
    public class CartController : Controller
    {
        [Route("index")]
        public IActionResult Index()
        {
            var cart = SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart");
            ViewBag.cart = cart;
            ViewBag.total = cart.Sum(item => item.Product.Price * item.Quantity);
            return View();
        }

        [Route("buy/{id}")]
        public IActionResult Buy(string id)
        {
            ProductModel productModel = new ProductModel();
            if (SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart") == null)
            {
                List<Item> cart = new List<Item>();
                cart.Add(new Item { Product = productModel.find(id), Quantity = 1 });
                SessionHelper.SetObjectAsJson(HttpContext.Session, "cart", cart);
            }
            else
            {
                List<Item> cart = SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart");
                int index = isExist(id);
                if (index != -1)
                {
                    cart[index].Quantity++;
                }
                else
                {
                    cart.Add(new Item { Product = productModel.find(id), Quantity = 1 });
                }
                SessionHelper.SetObjectAsJson(HttpContext.Session, "cart", cart);
            }
            return RedirectToAction("Index");
        }

        [Route("remove/{id}")]
        public IActionResult Remove(string id)
        {
            List<Item> cart = SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart");
            int index = isExist(id);
            cart.RemoveAt(index);
            SessionHelper.SetObjectAsJson(HttpContext.Session, "cart", cart);
            return RedirectToAction("Index");
        }

        private int isExist(string id)
        {
            List<Item> cart = SessionHelper.GetObjectFromJson<List<Item>>(HttpContext.Session, "cart");
            for (int i = 0; i < cart.Count; i++)
            {
                if (cart[i].Product.Id.Equals(id))
                {
                    return i;
                }
            }
            return -1;
        }

    }
}

Tạo View


Tạo thư mục Views. Trong thư mục này bạn tạo các views sau:

Product View

Tạo thư mục Product. Trong thư mục Views/Product, bạn tạo file Index.cshtml nội dung như sau:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>

    <h3>Products List</h3>
    <table cellpadding="2" cellspacing="2" border="1">
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Photo</th>
            <th>Price</th>
            <th>Buy</th>
        </tr>
        @foreach (var product in ViewBag.products)
        {
            <tr>
                <td>@product.Id</td>
                <td>@product.Name</td>
                <td><img src="~/images/@product.Photo" width="60" /> </td>
                <td>@product.Price</td>
                <td align="center">
                    <a asp-controller="cart" asp-action="buy" asp-route-id="@product.Id">Buy Now</a>
                </td>
            </tr>
        }
    </table>

</body>
</html>

Cart View


Tạo thư mục Cart. Trong thư mục Views/Cart, bạn tạo file Index.cshtml nội dung như sau: 

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>

    <h3>Cart Page</h3>
    <table cellpadding="2" cellspacing="2" border="1">
        <tr>
            <th>Option</th>
            <th>Id</th>
            <th>Name</th>
            <th>Photo</th>
            <th>Price</th>
            <th>Quantity</th>
            <th>Sub Total</th>
        </tr>
        @foreach (var item in ViewBag.cart)
        {
            <tr>
                <td><a asp-controller="cart" asp-action="remove" asp-route-id="@item.Product.Id">Remove</a></td>
                <td>@item.Product.Id</td>
                <td>@item.Product.Name</td>
                <td><img src="~/images/@item.Product.Photo" width="60" /> </td>
                <td>@item.Product.Price</td>
                <td>@item.Quantity</td>
                <td>@(item.Product.Price * item.Quantity)</td>
            </tr>
        }
        <tr>
            <td align="right" colspan="6">Sum</td>
            <td>
                @ViewBag.total
            </td>
        </tr>
    </table>
    <br>
    <a asp-controller="product" asp-action="index">Continue Shopping</a>

</body></html> 

Tạo Razor View Imports


Click phải thư mục Views chọn Add\New Item


Chọn Web\ASP.NET bên khung trái. Sau đó chọn Razor View Imports item và click Add để hoàn tất.


Trong file _ViewImports.cshtml thêm lệnh sau:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Toàn bộ cấu trúc của project sẽ như hình dưới:



Chạy Ứng Dụng


Tiến hành chạy ứng dụng web để xem kết quả. 

Trang Product/Index


Click Buy Now để mua sản phẩm và hiển thị trang giỏ hàng.

Trang Cart/Index