آموزش ساخت فروشگاه اینترنتی با ASP.NET MVC – بخش۳
آموزش ساخت فروشگاه اینترنتی با ASP.NET MVC - بخش3 » در این بخش، برای CartID سبدخرید، کوکی تعریف کرده و Controller و View سبدخرید را تکمیل خواهیم کرد.

 آموزش قدم به قدم ایجاد فروشگاه آنلاین با MVC – بخش سوم 

Online Shop by MVC – Step by Step Tutorial – Part3

 

در بخش دوم از آموزش فروشگاه اینترنتی با ASP.NET MVC ، نحوه نمایش محصولات یک فهرست را بهمراه اکشن، view های لازم را آموزش دادیم و در نهایت کلاس سبدخرید را ایجاد کردیم و توابع Add و Remove را برای آن تعریف و پیاده سازی کردیم.

 

تعریف کوکی برای CartId :

آیدی منحصر بفرد برای سبد خرید هر کاربر را در کوکی ذخیره می کنیم . زیرا فرض کنید کاربر امروز چند محصول را به سبدخرید اضافه کرده است و وقت تکمیل فرآیند خریدش را ندارد . این محصولات باید تا مدتی در سبدخرید او باقی بماند (در این مثال یک هفته) تا در این مدت ، هر بار که به فروشگاه مراجعه می کند آیتم هایی که قبلا به سبد خرید اضافه کرده است را مشاهده کند .

آیدی سبدخرید (CartId) را از نوع Guid تعریف می کنیم که یک رشته یکتا برمیگرداند .

تابع مربوطه بصورت زیر تعریف می شود :

 
private string GetCartId(HttpContextBase http)
{
    var cookie = http.Request.Cookies.Get("ShoppingCart");
    var cartId = string.Empty;
 
    if(cookie == null || string.IsNullOrWhiteSpace(cookie.Value))
    {
        cookie = new HttpCookie("ShoppingCart");
        cartId = Guid.NewGuid().ToString();
        cookie.Value = cartId;
        cookie.Expires = DateTime.Now.AddDays(7);
        http.Response.Cookies.Add(cookie);
    }
    else
    {
        cartId = cookie.Value;
    }
    return cartId;
}
                                           

در شرط if بررسی می شود که اگر cookie خالی است یک کوکی جدید برای کاربر بساز و اگر کوکی از قبل وجود دارد ، مقدارش را به cartId اختصاص دهد و return کند .

 

کنترولر ShoppingCart :

در کنترولر سبدخرید ، اکشنی بنام AddToCart ایجاد می کنیم که بصورت زیر تعریف می شود :

 
public ActionResult AddToCart(int id)
{
    var Cart = new ShoppingCart(HttpContext);
    Cart.Add(id);
    return (RedirectToAction("Index"));
}
                                           

Httpcontext را به کلاس ShoppingCart ارسال کرده ایم و در نهایت به صفحه سبدخرید redirect شده است .

اکشن RemoveFromCart را نیز مانند Add بدین صورت تعریف می کنیم :

 
public ActionResult RemoveFromCart(int id)
{
    var Cart = new ShoppingCart(HttpContext);
    Cart.Remove(id);
    return (RedirectToAction("Index"));
}
                                           

تست سبد خرید :

برای انجام تست کارکرد سبدخرید ، پروژه خود را اجرا کرده و آدرس زیر را در نوار آدرس بنویسید :

Shoppingcart/addtocart/2

در واقع از کنترولر ShoppingCart اکشن addtoCart را با پارامتر ۲ صدا زده ایم . با اجرای این آدرس ، پیام خطایی مبنی بر عدم وجود Index View نمایش داده می شود ( ولی نگران نباشید ، در مقاله بعد ویو را اضافه خواهیم کرد ! ) اکنون دیتابیس Management Studio را باز کنید و جدول cartItems را select کنید . با تصویر زیر روبرو خواهید شد :

تست سبد خرید

و اگر آدرس فوق را مجددا اجرا کنید ، ستون Count در تصویر فوق برابر ۲ خواهد شد .

حال می خواهیم حذف آیتم از سبدخرید را تست کنیم . بدین منظور ، آدرس زیر را پس از اجرای پروژه در نوار آدرس تایپ کرده و اینتر کنید :

Shoppingcart/removefromcart/2

پس از اجرای این آدرس ، مشاهده می کنید که یکی از محصولات با id=2 از سبدخرید پاک می شود .

تا اینجا ، از کوکی برای ذخیره سبدخرید در مرورگر کاربر استفاده کردیم و نیز سبدخرید را تست کردیم . در بخش بعد می خواهیم برای سبدخرید ، view ایجاد کنیم و دکمه افزودن به سبدخرید را در Details قرار دهیم .

نمایش سبد خرید

ایجاد View برای سبدخرید :

روی اکشن Index راست کلیک کنید و Add View را انتخاب کنید . در پنجره ظاهر شده ، Template را Empty انتخاب کنید و use layout را تیک بزنید و باکس را خالی رها کنید و Add را بفشارید .

دستورات و کدهای زیر را در Index View از ShoppingCartController تعریف کنید :


@model AspNetStore.ViewModels.ShoppingCartViewModel
@{
    ViewBag.Title = "Shopping Cart";
}

<h2>Review your <em> Cart</em></h2>

<hr />
<p class="btn btn-warning">
    @Html.ActionLink("Check Out", "Checkout")
</p>

<hr />
<div id="update-message">
    &nbsp;
</div>

<hr />
<div class="row">
    <div class="col-sm-12 table-responsive">
        @foreach(var item in Model.Items) { }

        <table class="table-bordered table-condensed table-hover table-striped">
            <tbody>
                <tr>
                    <th>
                        Name 
                    </th>
                    <th>
                        Price 
                    </th>
                    <th>
                        Quantity 
                    </th>
                </tr>
                <tr id="row-@item.CartItemId">
                    <td>
                        @Html.ActionLink(item.Product.Name, "Details", "Store", new { id=item.ProductId },null)
                    </td>
                    <td>
                        @item.Product.Price
                    </td>
                    <td id="item-count-@item.CartItemId">
                        @item.Count
                    </td>
                    <td>
                        @Html.ActionLink("Remove", "RemoveFromCart", new { id = item.ProductId,@class="text-danger" }, null)
                    </td>
                </tr>
                <tr>
                    <td>
                        Total : 
                    </td>
                    <td>
                        &nbsp;
                    </td>
                    <td>
                        &nbsp;
                    </td>
                    <td id="cart-total">
                        @Model.Total
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
 

توضیح : در خط اول ، مدل ورودی به این view را ShoppingCartViewModel تعریف کردیم  . سپس عنوان صفحه آمده است . در نهایت جدولی که شامل سبد خرید می باشد طراحی شده است . دارای چهار ستون است که نام و قیمت و تعداد و عملیات حذف می باشد . خروجی آن بصورت زیر می باشد :

سبد خرید خالی

افزودن دکمه به Details :

اکنون نوبت آنست که دکمه مربوط به افزون به سبد خرید (Add to Cart) را به Details View اضافه کنیم .

یک اکشن لینک در صفحه Details بصورت زیر قرار می دهیم :

 
@Html.ActionLink("Add to Cart", "AddToCart",
new { controller = "ShoppingCart",id=Model.ProductId})
                                           

حال اپلیکیشن را اجرا می کنیم و چند محصول بطور تستی به سبد خرید اضافه می کنیم تا عملیات موردنظر را تست کنیم :

سبدخرید آیتم دار

 

تا اینجای مقاله، برای سبدخرید ، view ایجاد کردیم و دکمه افزودن به سبدخرید را در Details قرار دادیم . در بخش بعد میخواهیم سراغ موضوع مهم پیاده سازی سفارشات کاربران (Orders) برویم .

 

سفارشات کاربران :

وقت آن رسیده است که کاربر ، آیتم های موجود در سبد خرید خود را نهایی کند و آنها را سفارش دهد .

برای نگهداری و ذخیره سفارشات کاربران ، به دو کلاس نیاز داریم . اولی Order که در آن تاریخ ثبت سفارش و اطلاعات کاربر و کد سفارش ذخیره می شود . کلاس دوم OrderDetail می باشد که شامل نام  محصولات سفارش داده و شده و قیمت و تعداد هر یک از آنها .

 

ایجاد کلاس OrderDetail  :

اولین کلاسی که برای بخش سفارشات فروشگاه خود می سازیم OrderDetail می باشد که بیانگر جدول OrderDetails در دیتابیس خواهد بود . این کلاس دارای کلید اصلی OrderDetailId و کلید خارجی (Foreign Key) OrderId می باشد :

 
public class OrderDetail
{
    [Key]
    public int OrderDetailId { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public virtual Product Product { get; set; }
    public virtual Order Order { get; set; }
}
                                           

ایجاد کلاس Order :

اکنون باید کلاسی تعریف کنیم که کلاس OrderDetail زیرمجموعه آن باشد . کلاس Order همانطور که قبلا ذکر شد ، شامل اطلاعات شخصی کاربر ، تاریخ ثبت سفارش و سایر فیلدها (بصورت زیر) می باشد :

 
public class Order
{
    [Key]
    public int OrderId { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime OrderDate { get; set; }

    [Required]
    public string TransactionId { get; set; }

    [Required]
    [StringLength(100)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(100)]
    public string LastName { get; set; }

    [Required]
    [StringLength(100,MinimumLength=10)]
    public string Address { get; set; }

    [Required]
    [StringLength(40)]
    public string City { get; set; }

    [Required]
    [StringLength(40)]
    public string State { get; set; }

    [Required]
    [StringLength(20, MinimumLength = 8)]
    public string PostalCode { get; set; }

    [Required]
    [StringLength(40)]
    public string Country { get; set; }

    [Required]
    [StringLength(24)]
    [DataType(DataType.PhoneNumber)]
    public string Phone { get; set; }

    [Required]
    public string Email { get; set; }
    [Required]
    public decimal Total { get; set; }

    public virtual List OrderDetails { get; set; }

    public Order()
    {
        OrderDetails = new List();
    }
}
                                           

نکته : همانطور که در دستور آخر مشاهده می کنید در سازنده کلاس Order از OrderDetail یک شئ ساختیم تا هر وقت که سفارشی ایجاد می شود ، OrderDetail برابر Null نباشد .

 

اعمال تغییرات در StoreContext :

برای اینکه این دو مدلی که در بالا ساختیم به جداول دیتابیس تبدیل شوند ، باید انها را در کلاس StoreContext تعریف کنیم :

public DbSet<Order> Orders { get; set; }

public DbSet<OrderDetail> OrderDetails { get; set; }

 

عملیات Migration :

پنجره Package Manager Console را باز کرده و دستور add-migration AddOrderInfo را تایپ  و اینتر کنید .

سپس دستور update-database را اجرا کنید . اکنون به دیتابیس پروژه ، دو جدول Orders , OrderDetails افزوده شده اند  :

بروز رسانی جدول محصولات

تا اینجا، کلاس های Orders و OrderDetails را ایجاد کردیم . تغییرات لازم را در StoreContext اعمال نمودیم و در نهایت Migration انجام دادیم . در این بخش میخواهیم برای عملیات Checkout یک اکشن و ViewModel و نیز تابع تعریف کنیم .

 

ایجاد اکشن برای Checkout :

نیاز به دو متد Get و Post داریم . اکشن Checkout با متد Get بصورت زیر تعریف می شود :

[HttpGet]
public ActionResult Checkout()
{
    return View();
}

و در اکشن با متد Post نیاز به CheckoutViewModel داریم . بنابراین ابتدا این کلاس را ایجاد می کنیم .

در فولدر ViewModels کلاسی بنام CheckoutViewModel بسازید و فیلدهای زیر را برای آن تعریف کنید :

 
   
     public class CheckoutViewModel
    {
        [Required]
        [StringLength(100)]
        [Display(Name=”First Name”)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(100)]
        [Display(Name = “Last Name”)]
        public string LastName { get; set; }

        [Required]
        [StringLength(100, MinimumLength = 10)]
        public string Address { get; set; }

        [Required]
        [StringLength(40)]
        public string City { get; set; }

        [Required]
        [StringLength(40)]
        public string State { get; set; }

        [Required]
        [StringLength(20, MinimumLength = 8)]
        [Display(Name = “Postal Code”)]
        public string PostalCode { get; set; }

        [Required]
        [StringLength(40)]
        public string Country { get; set; }

        [Required]
        [StringLength(24)]
        [DataType(DataType.PhoneNumber)]
        public string Phone { get; set; }

        [Required]
        [Display(Name = “Email Address”)]
        [RegularExpression(pattern:
        @"\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
        ErrorMessage="Email is not Valid !")]
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }

        public decimal Total { get; set; }
    }
                                           

 

ایجاد تابع Checkout در کلاس ShoppingCart.cs :

تابع فوق را بصورت زیر می نویسیم :

 
        public object CheckOut(CheckoutViewModel model)
        {
            var items = GetCartItems();
            var order = new Order()
            {
                FirstName = model.FirstName,
                LastName = model.LastName,
                Address = model.Address,
                City = model.City,
                Email = model.Email,
                Phone = model.Phone,
                PostalCode = model.PostalCode,
                State = model.State,
                Country = model.Country,
                OrderDate = DateTime.Now
            };
            foreach(var item in items)
            {
                var detail = new OrderDetail()
                {
                    ProductId = item.ProductId,
                    UnitPrice = item.Product.Price,
                    Quantity = item.Count,
                };
                order.Total += (item.Product.Price * item.Count);
                order.OrderDetails.Add(detail);
            }
              model.Total = order.Total;
            // TODO : Authorize payment
            // TODO : Assign TransactionId
            _db.Orders.Add(order);
            // if paymeny was successfull , order will saved in DB , otherwise it won't be saved .
            _db.SaveChanges();
            return null;
        }
                                           

توضیح : ورودی این تابع CheckoutViewModel و خروجی آن object است . زیرا نوع خروجی آن دقیقا مشخص نیست .

سپس از کلاس (مدل یا جدول) Order یک شئ می سازیم و مقادیر فیلدهایش را با مدل ورودی میدهیم . سپس به ازای هر آیتم از سبد خرید ، یک شئ از کلاس OrderDetail تعریف کرده و آنرا با دیتای داخل سبدخرید ، مقداردهی می کنیم . در نهایت جداول Order و OrderDetail را آپدیت می کنیم .

نکته : اگر پرداخت وجه توسط کاربر با موفقیت انجام شود ، دستور saveChanges را صدا می زنیم .

 

تعریف اکشن Checkout در کنترولر سبدخرید :

اکشن فوق در ShoppingCartController بصورت زیر تعریف خواهد شد :

 
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Checkout(CheckoutViewModel model)
        {
            if(!ModelState.IsValid)
            {
                return (View(model));
            }
            var cart = new ShoppingCart(HttpContext);
            var result = cart.CheckOut(model);
            return RedirectToAction("Index");
        }
                                           

تا اینجا، برای عملیات checkout ، اکشن و ViewModel تعریف کردیم . در این بخش می خواهیم برای تکمیل سفارش یا همان Checkout یک view طراحی کنیم.

 

ایجاد View برای اکشن Checkout :

روی اکشن Checkout راست کلیک کرده و Add View را انتخاب کنید . سپس تنظیمات View را بطور پیش فرض قرار میدهیم .

کدهای زیر را در این ویو تعریف خواهیم کرد :


@model AspNetStore.ViewModels.CheckoutViewModel
@{
    ViewBag.Title = "Checkout";
}
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

<h2>
    Checkout
</h2>

<fieldset>
    <legend> Shipping Information </legend>

    <div class="label">
        @Html.LabelFor(m => m.FirstName)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.FirstName)
    </div>

    <div class="label">
        @Html.LabelFor(m => m.LastName)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.LastName)
    </div>

    <div class="label">
        @Html.LabelFor(m => m.Address)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.Address)
    </div>

    <div class="label">
        @Html.LabelFor(m => m.Country)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.Country)
    </div>


    <div class="label">
        @Html.LabelFor(m => m.City)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.City)
    </div>


    <div class="label">
        @Html.LabelFor(m => m.State)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.State)
    </div>

    <div class="label">
        @Html.LabelFor(m => m.PostalCode)
    </div>

    <div class="editor">
        @Html.EditorFor(m => m.PostalCode)
    </div>

    <div class="label">
        @Html.LabelFor(m => m.Phone)
    </div>


    <div class="editor">
        @Html.EditorFor(m => m.Phone)
    </div>


    <div class="label">
        @Html.LabelFor(m => m.Email)
    </div>


    <div class="editor">
        @Html.EditorFor(m => m.Email)
    </div>

</fieldset>

<p>
    } 
</p>

حال نوبت آن رسیده است که پروژه را اجرا کنیم . قبل از اینکار روی متد Post از اکشن Checkout یک BreakPoint قرار دهید (مطابق شکل زیر) و روی Checkout View که باز است دکمه اجرای برنامه را بزنید . صفحه ای برای پر کردن اطلاعات شخصی کاربر نمایش داده می شود ، باکس های متنی را پر کنید و دکمه submit را بفشارید . اجرای برنامه وارد محل قرارگرفتن BreakPoint می شود . مطابق تصویر زیر اگر ModelState برابر true بود ، با زدن کلید F10 به مراحل بعدی اجرای بعدی بروید وگرنه باید چک کنید که کدام فیلد را مطابق انتظار ، پر نکردید .

اعتبارسنجی ModelState 

 

خب دوستان خسته نباشید . تا بدین جا در آموزش فروشگاه آنلاین با MVC ، بطور کلی مراحل زیر را انجام دادیم :

  • طراحی مدل های Category , Product , Order , OrderDetail , CartItem
  • طراحی و پیاده سازی سبد خرید (Shopping Cart)
  • ثبت سفارش کاربر طبق سبد خرید نهایی شده

 

در بخش چهارم از سری آموزشی فروشگاه اینترنتی با MVC ، خواهیم دید که چگونه فروشگاه اینترنتی خود را به درگاه پرداخت آنلاین متصل کنیم . همراه ما بمانید …frown


برچسب‌ها:

shopping cartShoppingcartاکشن Checkoutایجاد سبد خریدتعریف کوکیسبدخریدسورس کد سبد خریدفروشگاه آنلاینکنترولر سبدخرید

یک دیدگاه برای “آموزش ساخت فروشگاه اینترنتی با ASP.NET MVC – بخش۳”

  1. moslem aslani گفت:

    سلام
    من میخوام تا وقتی که کاربر دکمه تایید رو نزده محتوای سبد(محصولات و تعداد و ….) داخل کوکی باقی بمونه و بعد از تایید داخل دیتابیس ذخیره بشن.این کار رو کردم با کد زیر
    HttpCookie myCookie = Request.Cookies[“cart”];
    if (myCookie == null)
    {
    myCookie = new HttpCookie(“cart”);
    }
    myCookie.Expires = DateTime.Now.AddMinutes(10);
    myCookie.Values.Add(“product”, id.ToString());
    Response.Cookies.Add(myCookie);
    ShopService s = new ShopService();
    return s.CartProducts().Count;
    و چون Value بصورت زیر ذخیره میشه نمیدونم چطوری باید یه محصول رو از سبد پاک کنم؟؟؟
    ممنون میشم پاسخ بدین

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

هجده + دو =