Cart in ASP.NET Core 2.1
Tags: csharp, webdev
Published: 2020-06-20 03:48:00

Today,We will setup a example **create Cart in ASP.NET Core**
Github:[Cart in ASP.NET CORE 2.1](https://github.com/skipperhoa/cart-in-aspnet-core21)
The first, we need setup project ASP.NET CORE 2.1
Steps 1: Open /**Visual Studio 2019**. choose **File->new**, Select Project
Steps 2: Choose Create a project
Steps 3: Select **ASP.NET Core Web Application template**
Steps 4: You enter name project 
Steps 5: Select **.Net Core**, ASP.NET Core 2.1, choonse **Web Application(Model-View-Controller)**, after then click Create 

Okay, after setup complete project, you need open **Nutget Packager Manager->Install** (4 plugin)
```
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Newtonsoft.Json
```
Setup connect SQL SERVER, open **appsettings.json** File
```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "EFDataContext": "Server=DESKTOP-GCABV8F\\SQLExpress;Database=DB_Cart;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}
```
You can name The database arbitrary, because the we will run Migration, it will create the database in SQL SERVER, you can see the article : [Database Relationships(One to Many, Many to Many) in ASP.NET CORE 2.1](https://dev.to/skipperhoa/database-relationships-one-to-many-many-to-many-in-asp-net-core-2-1-5176)
Now, go to Models folder, create **Product.cs** class use set up properties data 
+ **Models/Product.cs**
```csharp
public class Product
    {
        public int idProduct { get; set; }
        public string Title { get; set; }
        public string UrlImage { get; set; }
        public string Detail { get; set; }
        public decimal Price { get; set; }
    }
```
Continue, you need create class extends from **DBContext**, Because **DBContext** class is important in **EntityFramewor Core**, Support connect the data to SQL SERVER
+ **Models/EFDataContext.cs** 
```csharp
using Microsoft.EntityFrameworkCore;
namespace CartASP_Core21.Models
{
    public class EFDataContext : DbContext
    {
        public EFDataContext(DbContextOptions<EFDataContext> options)
               : base(options) { }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>().HasKey(s => s.idProduct);

        }
        public DbSet<Product> Products { get; set; }
    }
}
```
Register **EFDataContext.cs** class in **Startup.cs** class
```csharp
public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddDbContext<EFDataContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("EFDataContext")));
        }
```
Okay, now we need run Migration: Open **Nuget Packager Manager->Package Nuget Console**
```
add-migration dbcart
update-database
```
Run migration complete, you check in SQL SERVER, it have create database
![Cart in ASP.NET Core 2.1](https://hoanguyenit.com/public/upload/images/cart-in-aspnet-core21.JPG)
Create sample data: Copy the image to the wwwrooot / images folder
![Cart in ASP.NET Core 2.1](https://hoanguyenit.com/public/upload/images/cart-in-aspnet-core21-01.JPG)

Okay, go to Models folder, create **Cart.cs** file 
+ **Models/Cart.cs** 
```csharp 
public class Cart
   {
       public Product Product { get; set; }
       public int Quantity { get; set; }
   }
```
When the customer buy the product, we add it to cart, we use session save cart 
If you want use Session in ASP.NET Core, you need register it in **Startup.cs** class, in **ConfigureServices**  method add the following code below
```csharp
services.AddSession(options => {
                options.IdleTimeout = TimeSpan.FromMinutes(30);
});

```
Configure method, add the line
```
app.UseSession();
```
You can see it:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-3.1
Okay, go to Controllers folder, create **ProductController.cs** 
```csharp
using Newtonsoft.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using CartASP_Core21.Models;
namespace CartASP_Core21.Controllers
{
    public class ProductController : Controller
    {
        private EFDataContext _db;
        // GET: Shop
        public ProductController(EFDataContext db)
        {
            this._db = db;
        }
        public ActionResult Index()
        {

            var _product = getAllProduct();
            ViewBag.product = _product;
            return View();
        }

    //GET ALL PRODUCT
        public List<Product> getAllProduct()
        {
            return _db.Products.ToList();
        }

        //GET DETAIL PRODUCT
        public Product getDetailProduct(int id)
        {
            var product = _db.Products.Find(id);
            return product;
        }

    }
}
```
In the code above, we insert **EFDataContext.cs** class, we use call to database 
+ **getAllProduct()**: get all the data product in database
+ **getDetailProduct(int id)**: Id search in The product, after then return the product
```csharp
//ADD CART
       public IActionResult addCart(int id)
       {
           var cart = HttpContext.Session.GetString("cart");//get key cart
           if (cart == null)
           {
               var product = getDetailProduct(id);
               List<Cart> listCart = new List<Cart>()
               {
                   new Cart
                   {
                       Product = product,
                       Quantity = 1
                   }
               };
               HttpContext.Session.SetString("cart", JsonConvert.SerializeObject(listCart));

           }
           else
           {
               List<Cart> dataCart = JsonConvert.DeserializeObject<List<Cart>>(cart);
               bool check = true;
               for (int i = 0; i < dataCart.Count; i++)
               {
                   if (dataCart[i].Product.idProduct == id)
                   {
                       dataCart[i].Quantity++;
                       check = false;
                   }
               }
               if (check)
               {
                   dataCart.Add(new Cart
                   {
                       Product = getDetailProduct(id),
                       Quantity = 1
                   });
               }
               HttpContext.Session.SetString("cart", JsonConvert.SerializeObject(dataCart));
               // var cart2 = HttpContext.Session.GetString("cart");//get key cart
               //  return Json(cart2);
           }

           return RedirectToAction(nameof(Index));

       }
```
+ **addCart(int id)**: insert the product to Cart 
- **HttpContext.Session.GetString("cart")**:set Key in Session save cart
- If cart==null: We need create **List<Cart> listCart = new List<Cart>()** save the first product
- If cart!=null: We use **JsonConvert.DeserializeObject<List<Cart>>(cart)** convert json to List<Cart>
- After then check it, If **(dataCart[i].Product.idProduct == id)**: we will set up quantity++;
- if **(dataCart[i].Product.idProduct != id)**: continue add product to cart
- Create a new Session containing new data
```csharp
public IActionResult ListCart()
        {
            var cart = HttpContext.Session.GetString("cart");//get key cart
            if (cart != null)
            {
                List<Cart> dataCart = JsonConvert.DeserializeObject<List<Cart>>(cart);
                if (dataCart.Count > 0)
                {
                    ViewBag.carts = dataCart;
                    return View();
                }
            }
            return RedirectToAction(nameof(Index));
        }
```
+ **ListCart()**: Display all the product in cart
- **HttpContext.Session.GetString("cart")**: get Session "cart"
- If **dataCart!=null**: we create **List<Cart>** save list cart
- after then in **ListCart.cshtml** file, display the data cart
```csharp
[HttpPost]
        public IActionResult updateCart(int id, int quantity)
        {
            var cart = HttpContext.Session.GetString("cart");
            if (cart != null)
            {
                List<Cart> dataCart = JsonConvert.DeserializeObject<List<Cart>>(cart);
                if (quantity > 0)
                {
                    for (int i = 0; i < dataCart.Count; i++)
                    {
                        if (dataCart[i].Product.idProduct == id)
                        {
                            dataCart[i].Quantity = quantity;
                        }
                    }


                    HttpContext.Session.SetString("cart", JsonConvert.SerializeObject(dataCart));
                }
                var cart2 = HttpContext.Session.GetString("cart");
                return Ok(quantity);
            }
            return BadRequest();

        }
```
+ **updateCart(int id, int quantity)**:  params (id,quantity), support update the product in cart
- **HttpContext.Session.GetString("cart")**: get all product in Session Key "cart"
- Create **List<Cart>** save cart
- Check the product, if **dataCart[i].Product.idProduct == id**, we need change **dataCart[i].Quantity = quantity**
```csharp
public IActionResult deleteCart(int id)
       {
           var cart = HttpContext.Session.GetString("cart");
           if (cart != null)
           {
               List<Cart> dataCart = JsonConvert.DeserializeObject<List<Cart>>(cart);

               for (int i = 0; i < dataCart.Count; i++)
               {
                   if (dataCart[i].Product.idProduct == id)
                   {
                       dataCart.RemoveAt(i);
                   }
               }
               HttpContext.Session.SetString("cart", JsonConvert.SerializeObject(dataCart));
               return RedirectToAction(nameof(ListCart));
           }
           return RedirectToAction(nameof(Index));
       }
```
+ **deleteCart(int id):** Check if the product id is in the cart, and if so, delete it
OKay, we need change **Startup.cs** file, call to **ProductController.cs**
```csharp
app.UseMvc(routes =>
{
   routes.MapRoute(
       name: "default",
       template: "{controller=Product}/{action=Index}/{id?}");
});
```
+ **Views/_ViewInport.cshtml:** insert two line the following code below
```csharp
@using Microsoft.AspNetCore.Http;
@using Newtonsoft.Json;
```
+ **Views/Shared/_Layout.cshtml :** Note, you need add the following code below, on top of the file
```csharp
@{
    var data = Context.Session.GetString("cart");

    int coutCart = 0;
    if (data == null)
    {
        coutCart = 0;
    }
    else
    {
        var data2 = Context.Session.GetString("cart");
        List<Cart> dataCart = JsonConvert.DeserializeObject<List<Cart>>(data2);
        foreach (var item in dataCart)
        {
            coutCart += item.Quantity;
        }

    }

}
```
The above code takes the shopping cart list through the session key 'cart', then counts it, how many products are in the cart, default = 0
Okay, open **_Layout.cshtml** file, Reworked seats RenderBody()
```csharp
<div class="container body-content">
        <br />

        <a asp-area=""
            asp-controller="Product"
            asp-action="ListCart" 
            style="background:#000;padding:10px;">Cart 
            <img src="~/images/cart.png" style="width:25px !important;height:25px;display:inline-block;" />
            @coutCart
         </a>

        <br />
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2020 - CartASP_Core21</p>
        </footer>
</div>
```
+ **Views/Product/Index.cshtml**
```csharp
@model CartASP_Core21.Models.Product;
@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<style>
    .list-product {
        width: 1200px;
        margin: auto;
        display: flex;
        flex-wrap: wrap;
    }

    .product {
        margin-top: 10px;
        margin-right: 10px;
        width: 120px;
        height: 200px;
    }

    img {
        width: 100px;
        height: 100px;
        display: block;
        margin: auto;
    }

    .title {
        display: block;
        font-size: 15px;
        font-weight: bold;
        text-align: center;
    }

    .viewProduct, .addProduct {
        width: calc((100% - 2px) / 2);
        display: inline-block;
        float: left;
        padding: 2px;
        font-size: 12px;
        box-sizing: border-box;
        color: #fff;
        background: #808080;
        text-decoration: none;
        text-align: center;
    }

    .addProduct {
        margin-left: 2px;
    }
</style>

<div class="list-product">
    @foreach (var item in ViewBag.product)
    {
    <div class="product">
        <img src="~/images/@item.UrlImage" class="img-responsive" />
        <span class="title">@item.Title</span>
        <a href="" class="viewProduct">View</a>
        <a asp-controller="Product" asp-action="addCart" asp-route-id="@item.idProduct" class="addProduct">Add order</a>
    </div>
    }


</div>
```
![Cart in ASP.NET Core 2.1](https://hoanguyenit.com/public/upload/images/cart-in-aspnet-core21-02.JPG)
+ **Views/Product/ListCart.cshtml**
```csharp
@{
    ViewData["Title"] = "ListCart";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<style>
    td, th {
        padding: 10px;
    }
</style>
<script src="~/js/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        $(".updateCart").click(function (event) {
            event.preventDefault();
            var quantity = $(".quantity_" + $(this).attr("data-id")).val();
            console.log(quantity);
            $.ajax({
                type: "POST",
                url:"@Url.Action("updateCart","Product")",
                data: {
                    id: $(this).attr("data-id"),
                    quantity:quantity
                },
                success: function (result) {
                    window.location.href = '@Url.Action("ListCart","Product")';
                }
            });
        });
    });
</script>
<div class="list-cart">
    <table class="cart" border="1">
        <tr>
            <th>STT</th>
            <th>Title</th>
            <th>Image</th>
            <th>Quantity</th>
            <th>Price</th>
            <th>Total Price</th>
            <th>Update</th>
            <th>Delete</th>
        </tr>
        @{
            int STT = 0;
            foreach (var item in ViewBag.carts)
            {
                string txt_class = "quantity_" + item.Product.idProduct;
                STT++;
                int total = item.Product.Price * item.Quantity;
                <tr>
                    <td>@STT</td>
                    <td>@item.Product.Title</td>
                    <td><img src="~/images/@item.Product.UrlImage" width="100" height="100" /></td>
                    <td><input type="number" class="@txt_class" value="@item.Quantity" /></td>
                    <td>@item.Product.Price</td>
                    <td>@total</td>
                    <td><a href="" data-id="@item.Product.idProduct" class="updateCart">Update</a></td>
                    <td><a asp-controller="Product" asp-action="deleteCart" asp-route-id="@item.Product.idProduct">Delete</a></td>
                </tr>
            }
        }

    </table>
</div>
```
![Cart in ASP.NET Core 2.1](https://hoanguyenit.com/public/upload/images/cart-in-aspnet-core21-03.JPG)
The Article : [Cart in ASP.NET Core 2.1](https://hoanguyenit.com/cart-in-aspnet-core-21.html)