آموزش ساخت فروشگاه اینترنتی با ASP.NET MVC

آموزش قدم به قدم ایجاد فروشگاه آنلاین با MVC – بخش اول
Online Shop by MVC – Step by Step Tutorial – Part1
با سلام خدمت دوستان و همراهان همیشگی آکادمی راهکاری نو . در این سری آموزشی ، قصد داریم با هم یک فروشگاه اینترنتی نسبتا ساده ولی کامل را توسط ASP.NET MVC راه اندازی کنیم .
مزایای فروشگاه آنلاین برای کاربران و صاحبین مشاغل:
فوابد خرید اینترنتی برای کاربران و مشتریان:
در سال های اخیر، انجام خرید اینترنتی تا حد زیادی بین کاربران محبوب شده است و از مزایای خرید آنلاین برای خریداران و کاربران می توان به موارد زیر اشاره کرد:
- عدم محدودیت زمان و مکان
- مقایسه قیمت محصولات
- مشاهده نظرات سایر مشتریان
- و…
فواید راه اندازی فروشگاه اینترنتی برای کسب و کارها:
داشتن فروشگاه آنلاین برای کسب و کارها می تواند فواید زیر را داشته باشد:
- فروش 24 ساعته
- عدم محدودیت جغرافیایی برای مشتریان
- عدم نیاز به اجاره ملک یا فروشگاه فیزیکی
- آنالیز دقیق خریداران
- و…
مواردی که باید قبل از شروع خواندن این مقاله فرا گرفته باشید عبارتند از :
- ASP.NET MVC 5
- Entity Framework 6 – Code First (برای فراگیری این تکنولوژی به وب سایت asp.net مراجعه کنید)
- فریم ورک BootStrap (آموزش کامل در وب سایت مرجع بوت استرپ به نشانی getBootstrap.com)
در بخش اول آموزش “راه اندازی فروشگاه آنلاین توسط ASP.NET-MVC5” سرفصل های زیر را خواهیم داشت:
- نصب نرم افزارهای موردنیاز » نرمافزارهای اس کیو ال سرور و ویژوال استودیو » نصب Web Essentials
- ساخت پروژه جدید در Visual Studio » ایجاد Controller » ایجاد Action » » تعریف اکشن Index » تعریف اکشن Browse » تعریف اکشن Details » ایجاد View » نصب Bootstrap و Jquery » طراحی Layout » افزودن منو (navbar) به صفحه » ایجاد فایل ViewStart » تعریف Model » تعریف Connection String
- نصب Entity Framework » ایجاد کلاس Category » ایجاد کلاس Product » تعریف کلاس DatabaseContext
- ورود دیتا به جداول دیتابیس » روشهای مقداردهی به جداول product و category
نصب نرم افزارهای موردنیاز :
برای شروع این پروژه نیاز به دو نرم افزار VisualStudio و Microsoft SqlServer دارید.
نرمافزارهای اس کیو ال سرور و ویژوال استودیو:
نسخه های پیشنهادی ما برای این آموزش VisualStudio 2013 و Sqlserver 2014 یا ورژن های بالاتر می باشد ولی اگر Sqlserver 2012 را روی سیستم خود نصب دارید مشکلی ندارد و می توانید با همین نسخه ، این آموزش را پی بگیرید .
نصب Web Essentials
پس از نصب و راه اندازی ویژوال استودیو ، می بایست یک Extension به آن اضافه کنیم . بنابراین به منوی زیر رفته و Web Essentials 2013 را جستجو و نصب می کنیم : Tools > Extensions & Updates
ساخت پروژه جدید در Visual Studio:
به منوی File > New > Project بروید و در منوی سمت چپ web را انتخاب کرده و در منوی راست ، Asp.net Web Application و آخرین نسخه دات نت فریم ورک را انتخاب کرده (مانند تصویر زیر) و نام پروژه را AspNetStore قرار می دهیم و تیک گزینه Add to Source control را نیز می زنیم و OK میکنیم :
در مرحله بعد ، پنجره ای برای انتخاب تمپلیت پروژه نمایش داده می شود . گزینه Empty را از بالا و گزینه MVC را از پایین انتخاب کرده و Ok می کنیم :
در پایان ، از ما درباره نوع Source Control پرسیده می شود که گزینه Git را انتخاب میکنیم .
» مطالعه مقاله آموزشی گیت و گیت هاب توصیه می شود.
در بخش بعد، شروع به ایجاد Controller , Action , View مورد نیاز خواهیم کرد . همراه ما باشید …
ایجاد Controller :
به این منظور روی فولدر Controller راست کلیک کرده و Add > Controller را زده و نام آنرا HomeController قرار می دهیم . اگر Resharper را نصب کرده باشیم دستورات داخل کنترولر Home بصورت زیر می باشد :
کنترولر بعدی که ایجاد می کنیم StoreController می باشد که مانند HomeController ساخته می شود .
ایجاد Action :
تعریف اکشن Index:
اکشن Index از کنترولر Store را بصورت زیر تغییر می دهیم :
public ActionResult Index()
کار اکشن ایندکس نمایش محصولات بصورت رندوم می باشد .
تعریف اکشن Browse:
در همین کنترولر (Store) اکشن دیگری بنام Browse داریم که فعلا بصورت زیر تعریف می کنیم :
public ActionResult Browse(string id) { return View(); }
کار این اکشن نمایش محصولات یک دسته خاص است .
تعریف اکشن Details:
اکشن بعدی که مشخصات محصول را نمایش می دهد Details می باشد که بصورت زیر تعریف می شود :
public ActionResult Details(int id) { return View(); }
به اکشن های فوق ، در بخش های بعدی مقاله ، دستورات دیگری اضافه خواهیم کرد .
ایجاد View :
اکنون می خواهیم به هر یک از اکشن های فوق یک View نسبت دهیم . ابتدا باید فایل Layout را تعریف کنیم (که عملکردش مانند MasterPage در ASP.NET webform می باشد) بنابراین روی فولدر Views راست کلیک کرده و یک زیرفولدر بنام Shared می سازیم و روی این فولدر راست کلیک کرده و Add > View را انتخاب می کنیم و مانند تصویر زیر تنظیماتش را انجام می دهیم :
با توجه به اینکه ما میخواهیم از فریم ورک بوت استرپ برای طراحی قالب این فروشگاه استفاده کنیم ، نیاز داریم که نوگت jQuery و نیز Bootstrap را نصب کنیم .
نصب Bootstrap و Jquery :
روی فولدر References پروژه خود راست کلیک کرده و Manage NuGet Package را انتخاب می کنیم .
نکته : دقت کنید که ابتدا باید جی کوئری را نصب کنیم و سپس بوت استرپ .
پس در پنجره باز شده عبارت jquery را سرچ کرده و اولین گزینه یافت شده را Install می کنیم .
سپس عبارت bootstrap را جستجو کرده و اولین گزینه را install می کنیم .
در بخش بعد، با ایجاد Layout برای پروژه آشنا می شویم . با ما باشید …
طراحی Layout :
در این مرحله ، باید کدهای بوت استرپی موردنظر را در فایل Layout بنویسیم . ابتدا در تگ head کدهای زیر را می نویسیم :
<head> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title - AspNet Store</title> <link href="~/Content/bootstrap.min.css" rel="stylesheet" /> <link href="~/Content/Custom.css" rel="stylesheet" /> <script src="~/Scripts/jquery-2.2.0.min.js"></script> </head>
توضیح : اولین دستور (متا تگ) مربوط به ریسپانسیو بودن وب سایت می باشد . دستور دوم نیز عنوان وب سایت را مشخص می کند . در خط سوم استایل بوت استرپ را اضافه کردیم و در خط چهارم استایلی که خودمان می خواهیم به وب سایت اضافه کنیم را اضافه کردیم . و در نهایت در خط آخر نیز کتابخانه جی کوئری را رفرنس دادیم .
افزودن منو (navbar) به صفحه:
اکنون می خواهیم یک منو به صفحه اضافه کنیم . دستورات زیر را در تگ body تایپ کنید :
<nav class="navbar navbar-default navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> <code><button class="navbar-toggle collapsed" type="button"><span class="sr-only">Toggle navigation</span></button> @Html.ActionLink("AspNet Store", "Index", "Home", null, new { @class = "navbar-brand" }) </code> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"> <code>@Html.ActionLink("Home", "Index", "Home")</code> </li> </ul> </div> </div> </nav>
توضیح : توسط این دستورات ، منویی تعریف شده است که ویژگیهای زیر را دارد :
- در هنگام اسکرول ، به بالای صفحه می چسبد (fixed-top)
- در دستگاه های کوچک مانند موبایل بجای منو ، یک button نمایش داده می شود که با فشردن آن ، منو بصورت آبشاری به کاربر نمایش داده می شود .
- دارای Navbar-Brand است یعنی لوگو و یا نام سایت را در کنار منو نشان می دهد که در اینجا توسط ActionLink به اکشن ایندکس از کنترولر Home لینک داده ایم .
- لینکهای منو فعلا یکی است که به همین صفحه اصلی سایت اشاره دارد .
نکته : برای کسب اطلاعات بیشتر در زمینه منوی بوت استرپ ، به وب سایت getBootStrap مراجعه کنید .
ایجاد فایل ViewStart :
روش هوشمندانه تعریف Layout برای View های پروژه ، تعریف Layout در فایلیست بنام ViewStart . بنابراین روی فولدر Views راست کلیک کرده و Add > View را می زنیم . سپس بصورت شکل زیر مشخصات آنرا تعریف کرده و Add می کنیم :
و سپس دستور زیر را در فایل ViewStart تعریف می کنیم :
@{ Layout = @"~/Views/Shared/_Layout.cshtml"; }
از این پس ، فقط کافیست در هنگام افزودن view به یک اکشن ، تیک گزینه use a layout page را بزنیم ولی در باکس مربوطه چیزی ننویسیم . خودش بطور اتوماتیک از طریق فایل ViewStart ، فایل Layout را می بیند .
در مرحله بعد ، باید برای اکشن Index از کنترولر Home و اکشن های Index , Browse , Details ، یک View بسازیم. برای اینکار ، روی نام اکشن موردنظر راست کلیک کرده و Add > View را میزنیم و فقط تیک use layout را زده و Add میکنیم .
خب دوستان عزیز ، در بخش بعد، مدل های Category و Product و DatabaseContext و رشته اتصال به دیتابیس (Connection String) را خواهیم ساخت . همراه ما باشید …
تعریف Model :
برای شروع کار با مدل و دیتابیس ، ابتدا باید رشته اتصال به دیتابیس را در فایل web.config تعریف کنیم .
تعریف Connection String :
برای راهنمایی در این زمینه می توانید به وب سایت ConnectionStrings مراجعه کنید . در این وب سایت ، به قسمت Trusted Connection بروید و رشته اتصال آنرا کپی و در فایل web.config آنرا پیست کنید . این رشته اتصال ، راحتترین روش اتصال به دیتابیس می باشد چون نیازی به username , password ندارد :
Server=myServerAddress;Database=myDataBase;Trusted_Connection=True;
تنها چیزی که باید به رشته فوق اضافه کنیم ProviderName است. در نهایت باید رشته اتصال را در فایل web.config بعد از تگ appSetting و قبل از system.Web تعریف کنیم.
در این مثال ، نام سرور را نقطه (.) در نظر گرفتیم (معمولا نقطه می باشد) و نام دیتابیس را AspNetStore تعریف کردیم .
نصب Entity Framework :
مرحله بعدی ، نصب Entity Framework بر روی پروژه است . بنابراین مجددا از نوگت استفاده می کنیم . روی فولدر References راست کلیک کرده و Mange NuGet Packages را انتخاب میکنیم و در پنجره ظاهر شده ، EntityFramework را نصب می کنیم .
ایجاد کلاس Category :
روی فولدر Models راست کلیک کرده و Add > Class را بزنید و نام آنرا Category.cs قرار دهید و property های زیر را برای آن تعریف کنید :
public int CategoryId { get; set; } public string Name { get; set; }
ایجاد کلاس Product :
روی فولدر Models راست کلیک کرده و Add > Class را بزنید و نام آنرا Product.cs قرار دهید و فعلا property های زیر را برای آن تعریف کنید :
public int ProductId { get; set; } public string Name { get; set; } public Category Category { get; set; }
در مقاله های بعدی ، فیلدهای دیگری به جدول محصولات اضافه خواهیم کرد (مانند قیمت و توضیحات) . آخرین Property در کلاس فوق Category محصول است که از نوع کلاس Category می باشد که در بالا تعریف کردیم .
تعریف کلاس DatabaseContext :
برای ایجاد کلاسی به منظور ارتباط با دیتابیس ، یک فولدر بنام Data در روت پروژه خود بسازید و در آن کلاسی بنام StoreContext تعریف کنید . این کلاس باید از DbContext ارث ببرد . و همچنین در این کلاس ، باید دو کلاسی که در بالا تعریف کرده ایم را با نوع DbSet تعریف کنیم . بصورت زیر :
public class StoreContext : DbContext { public StoreContext() : base("DefaultConnection") { } public DbSet Categories { get; set; } public DbSet Products { get; set; } }
دقت کنید که در سازنده کلاس ، رشته اتصال را تعریف کرده ایم و در دستورات بعدی جداول محصولات و دسته ها را ساختیم .
تا اینجای مقاله، نوگت EntityFramework را نصب کردیم و کلاسهای Category , Product , DatabaseContext را تعریف کردیم . در بخش بعد میخواهیم به جداول محصولات و فهرست ، دیتای نمونه وارد کنیم .
ورود دیتا به جداول دیتابیس :
برای اینکه مدل های ما به جدول در دیتابیس تبدیل شوند ، باید یکبار پروژه را اجرا کنیم . بنابراین نوبت به اجرای اپلیکیشن رسیده است !
پس از اجرای اپلیکیشن ، می بینیم که در دیتابیس ، دو جدول ما ایجاد شده اند (تصویر زیر) :
روشهای مقداردهی به جداول product و category:
چند روش برای مقدار دهی به رکوردهای این جداول وجود دارد . یکی اینکه همینجا در دیتابیس روی جدول راست کلیک کنیم و Edit Top 200 Rows را بزنیم و مقادیر مورد نظر را وارد کنیم .
روش دیگر آنست که در پروژه روی Controllers راست کلیک کنیم و Add Controller کنیم و در پنجره ای که نمایش داده می شود ، گزینه MVC5 controller with views , using Entity Framework را انتخاب کنیم و در نهایت مدل خود را انتخاب کرده و OK کنیم . حال ، تمام قابلیتهای Insert , Update , Select , Delete بطور خودکار و با تمام View هایشان ، ایجاد می شوند . از طریق اجرای فایل Create.cshtml می توان به جدول موردنظر دیتا وارد کرد .
روش دیگر آنست که یک کلاس بنام DbPopulate.cs در فولدر Data تعریف کنیم . دستوراتی که در این کلاس می نویسیم بصورت زیر است :
public class DbPopulate { public async static Task AddDataAsync() { using (var db = new StoreContext()) { var Computers = new Category() { Name = "Computers" }; var Printers = new Category() { Name = "Printers" }; var Books = new Category() { Name = "Books" }; db.Categories.AddRange(new Category[] { Computers, Printers, Books }); db.Products.Add(new Models.Product { Name = "Really Fast Computer", Category = Computers }); db.Products.Add(new Models.Product { Name = "Midium Computer", Category = Computers }); db.Products.Add(new Models.Product { Name = "Color Laser 1", Category = Printers }); db.Products.Add(new Models.Product { Name = "Laser Jet 2", Category = Printers }); db.Products.Add(new Models.Product { Name = "Gone with the wind", Category = Books }); db.Products.Add(new Models.Product { Name = "Shahzadeh !", Category = Books }); db.SaveChanges(); } } }
مشاهده می کنید که برای جدول فهرست محصولات ، سه دسته تعریف کردیم و برای هر دسته 2 محصول .
میخواهیم این کلاس و دستوراتش را در اکشن Index از کنترولر Home اجرا کنیم . پس باید اکشن ایندکس نیز Async شود :
public async Task Index() { await DbPopulate.AddDataAsync(); return View(); }
نکته : پس از اجرای پروژه ، دیتاهای فرضی ، به جداول اضافه خواهند شد (تصویر زیر) :
آموزش قدم به قدم ایجاد فروشگاه آنلاین با MVC – بخش دوم
Online Shop by MVC – Step by Step Tutorial – Part2
در بخش اول از آموزش فروشگاه اینترنتی با MVC نرم افزارهای موردنیاز را معرفی و نصب کردیم. سپس یک پروژه mvc بهمراه سورس کنترل Git ایجاد کردیم و Controller ، Action و View لازم را تعریف کردیم و Layout موردنظر را طراحی کردیم و در نهایت مدل های لازم و رشته اتصال به دیتابیس را تعریف کردیم. با بخش دوم از این آموزش در خدمت شما هستیم.
این بخش از مقالات آموزشی “طراحی فروشگاه آنلاین با ASP.NET-MVC” شامل سرفصل های زیر است:
- نمایش محصولات به کاربر
تعریف کلاس StoreService.cs و آپدیت اکشن Index - نمایش محصولات یک فهرست
تابع DisplayProductsOf و تکمیل اکشن Browse - طراحی Browse View
تکمیل اکشن Details - طراحی Details View
افزودن فیلد های Price و Image و پیاده سازی سبد خرید (Shopping Cart) - ایجاد کلاس ShoppingCart
تابع Add و تابع Remove
نمایش محصولات به کاربر :
برای دسترسی به اطلاعات دیتابیس ، می توان در اکشن مربوطه ، بطور مستقیم ، از StoreContext که در مقالات قبل نوشتیم ، استفاده کنیم . ولی ما در این مقاله قصد داریم برای تعامل با دیتابیس ، از سرویس استفاده کنیم . بنابراین در روت پروژه ، یک فولدر بنام Services بسازید و در آن یک کلاس بنام StoreService.cs ایجاد کنید .
تعریف کلاس StoreService.cs:
دستورات زیر را در کلاس StoreService.cs می نویسیم :
public class StoreService { private readonly StoreContext _db; public StoreService() : this(new StoreContext()){} public StoreService(StoreContext context) { _db = context; } public IEnumerable GetCategories() { return _db.Categories.OrderBy(c => c.Name).ToArray(); } }
توضیح : ابتدا از کلاس StoreContext یک شئ ساختیم و با پارامتر ورودی این کلاس آنرا مقداردهی می کنیم . سپس تابع GetCategories را برای دریافت فهرست محصولات از دیتابیس تعریف کرده ایم .
حال باید تغییراتی در StoreController ایجاد کنیم . دستورات زیر را به ابتدای کنترولر اضافه کنید :
private readonly StoreService _store; public StoreController() : this(new StoreService()) { } public StoreController(StoreService service) { _store = service; }
در دستورات فوق ، از کلاس StoreService که قبلا نوشتیم یک شئ ساختیم و آنرا با پارامتر ورودی سازنده کنترولر مقداردهی کردیم .
آپدیت اکشن Index:
اکشن Index را نیز بصورت زیر تغییر می دهیم :
public ActionResult Index() { var categories = _store.GetCategories(); return View(categories); }
با اجرای Index View از کنترولر Store ، خروجی زیر را مشاهده خواهیم کرد :
نمایش محصولات یک فهرست :
تابع DisplayProductsOf:
برای اینکه با کلیک روی لینکهای تصویر فوق ، محصولات آن دسته نمایش داده شود ، تابعی بنام DisplayProductsOf در Service می نویسیم :
public IEnumerable DisplayProductsOf(string category) { return _db.Products.Where(p => p.Category.Name == category).OrderBy(p => p.Name).ToArray(); }
توضیح : این تابع رشته ای بنام فهرست را میگیرد و محصولاتی که زیرمجموعه این دسته هستند را بعنوان خروجی باز میگرداند .
تکمیل اکشن Browse:
حال نوبت آنست که اکشن Browse در StoreController را تکمیل کنیم :
public ActionResult Browse(string id) { var products = _store.DisplayProductsOf(id); if(!products.Any()) { return HttpNotFound(); } return View(products); }
تا اینجای مقاله، اکشن نمایش category را نوشتیم و توانستیم در خروجی پروژه ، عناوین فهرست محصولات را ببینیم . در بخش بعد، Browse View را ایجاد خواهیم کرد و اکشن Details را تکمیل می کنیم .
طراحی Browse View :
برای نمایش محصولات یک دسته ، باید تغییراتی در ویوی Browse اعمال کنیم . دستورات این ویو بصورت زیر می باشد :
@model IEnumerable @{ string currentCategory = Model.First().Name; ViewBag.Title = "Browse " + currentCategory; } <h2>Browse Products of <b> @currentCategory</b></h2> <div class="category"> <ul class="list-unstyled" id="category-list"> @foreach (var product in Model) { <li class="col-xs-4 col-sm-2 container"> <code><a href="@Url.Action("><img alt="@product.Name" src="~/Images/Sample_Product.png" /> </a></code> </li> } </ul> </div>
توضیح : ابتدا ، لیستی از محصولات را بعنوان مدل این View تعریف کرده ایم و سپس عنوان صفحه را متناسب با نام فهرست ، در نظر گرفته ایم . در یک لیست افقی ، برای هر محصول ، یک باکس طراحی شده که شامل تصویر محصول ، لینک مشخصات محصول و نام محصول است . خروجی بصورت زیر می شود :
تکمیل اکشن Details :
برای نمایش جزئیات یک محصول ، اکشن Details را ایجاد کردیم و برای استفاده از این اکشن ، در کلاس StoreService ، تابع زیر را می نویسیم :
public Product ProductDetail(int id) { return _db.Products.Include("Category").Where(p => p.ProductId == id).SingleOrDefault(); }
سپس اکشن Details را بصورت زیر تکمیل می کنیم :
public ActionResult Details(int? id) { if (!id.HasValue) { return HttpNotFound(); } var product = _store.ProductDetail(id.Value); if(product == null) { return HttpNotFound(); } return View(product); }
توضیح : اکشن Details پارامتر id را بعنوان ورودی می گیرد و سپس به تابع ProductDetail از کلاس StoreService میفرستد .
در این تابع ، اگر محصولی با این id یافت شد که اطلاعاتش به اکشن ارسال می شود و سپس اکشن به view متناظرش میفرستد . و اگر محصولی با id ارسالی یافت نشد صفحه HttpNotFound نمایش داده می شود .
تا اینجای مقاله، browse view را طراحی کردیم و نیز اکشن Details را کامل کردیم . در بخش بعد میخواهیم Details View را تکمیل کنیم و فیلدهای Price و Image را به جدول محصولات اضافه کنیم .
طراحی Details View :
در این مرحله باید View متناظر اکشن Details را طراحی کنیم . هنگامی که روی محصول در تصویر بالا ، کلیک می کنیم ، به صفحه مشخصات محصول (Details) هدایت خواهیم شد . در این مرحله ، میخواهیم کدهای لازم برای ویوی Details را بنویسیم :
@model AspNetStore.Models.Product @{ ViewBag.Title = @Model.Name + "Details"; } <h2>Details of @Model.Name</h2> <hr /> <div> <img alt="@Model.Name" src="~/Images/Sample_Product.png" /> </div> <div id="product_detail"> <p> <b>Name : </b> @Model.Name </p> <p> <b>Category : </b> @Model.Category.Name </p> <p> <button class="btn btn-success">Add to Cart</button> </p> </div>
توضیح : ابتدا جدول محصول را بعنوان مدل به این view ارسال کرده ایم و سپس عنوان صفحه را تعیین کردیم و در نهایت در div با id=product_detail مشخصات محصول را بیان کرده ایم . خروجی بصورت تصویر زیر خواهد شد :
افزودن فیلد های Price و Image :
در این مرحله می خواهیم دو فیلد ضروری قیمت و تصویر محصول را به مدل Product اضافه کنیم . اگر بطور مستقیم تغییرات را در مدل محصول اعمال کنیم و پروژه را اجرا کنیم ، اطلاعات و رکوردهایی که از قبل در دیتابیس موجود می باشد ، پاک می شوند . برای جلوگیری از این فاجعه ! باید بصورت زیر عمل کنیم .
استفاده از Migration :
به منوی Tools > NuGet Package Manager بروید و Package Manager Console را اجرا کنید . در خط فرمان دستور enable-migrations را تایپ کنید . پس از انجام عملیات توسط نوگت ، با پیغام زیر مواجه خواهید شد :
Code First Migrations enabled for project AspNetStore
در مرحله بعد ، کلاس product را باز کرده و تغییرات زیر را در آن اعمال کنید (دو فیلد زیر را به آن بیافزایید) :
public decimal Price { get; set; } public string ImageUrl { get; set; }
سپس دوباره به کنسول نوگت باز گردید و دستور add-migration UpdateProduct را تایپ کنید و Enter را بزنید . دقت کنید که UpdateProduct نام دلخواه می باشد .
در نهایت دستور update-database را در خط فرمان کنسول تایپ کرده و اینتر را بزنید .
کنسول نوگت پس از اجرای این دستورات به شکل زیر خواهد بود :
پس از انجام عملیات فوق ، در نرم افزار SqlServer ، ستونهای جدول product به شکل زیر خواهند بود :
» مطالعه مقاله کاملی راجع به Migration در Entity Framework Code-First
دوستان ، تا بدین جای مقاله، طراحی DetailsView را انجام دادیم و سپس دو فیلد قیمت و تصویر محصول را به جدول محصولات اضافه کردیم . و در نهایت Migration انجام دادیم . در این بخش میخواهیم ویوی محصولات را برای نمایش دو فیلد جدید تغییر دهیم و نیز در ادامه ، شروع به نوشتن کدهای سبدخرید کنیم .
تغییرات Views :
هم اکنون نیاز است تغییراتی در ویوهای موجود اعمال کنیم تا قیمت و تصویر محصول را نمایش دهند . به ویوی Details رفته و تصویر و قیمت محصول را بصورت زیر تعریف کنید :
Price : @Html.DisplayFor(m => m.Price)
حالا ویوی Browse را باز کنید و تصویر را بصورت زیر تعریف کنید :
ورود دیتا به فیلدهای قیمت و تصویر :
نرم افزار SqlServer را باز کرده و New Query را بزنید . دستور زیر را در خط فرمان آن بنویسید :
update Products set ImageUrl = '~/Images/Sample_Product.png'
برای تغییر مقدار فیلد قیمت محصولات ، روی جدول محصولات راست کلیک کنید و سپس Edit را بزنید و در اینجا قیمتهای دلخواه خود را وارد کنید .
پیاده سازی سبد خرید (Shopping Cart) :
به منظور شروع پیاده سازی سبدخرید ، روی فولدر Models راست کلیک کنید و یک کلاس بنام CartItem.cs به آن اضافه کنید . Property های زیر را در این کلاس تعریف کنید :
public class CartItem { [Key] public int CartItemId { get; set; } [Required] public string CartId { get; set; } public int ProductId { get; set; } public int Count { get; set; } [DataType(DataType.DateTime)] public DateTime DateCreated { get; set; } public virtual Product product { get; set; } }
آپدیت کلاس StoreContext.cs:
در مرحله بعد ، برای اضافه شدن این مدل به دیتابیس ما بعنوان یک جدول ، دستور زیر را در کلاس StoreContext.cs واقع در فولدر Data اضافه کنید :
public DbSet CartItems { get; set; }
افزودن جدول CartItems به دیتابیس از طریق Migration:
بدلیل اینکه تغییراتی در جداول و مدلهای دیتابیس رخ داده است ، باید مجددا از Migration استفاده کنیم تا جدول CartItems به دیتابیس ما اضافه شود .
کنسول NuGet را اجرا کرده و ابتدا دستور add-migration AddCartItem را بنویسید و اینتر کنید . سپس دستور آپدیت دیتابیس (update-database) را اجرا کنید . اکنون با مراجعه به دیتابیس مشاهده می کنیم که جدول CartItems ایجاد شده است .
در بخش قبل ، view را مطابق با فیلدهای جدید قیمت و تصویر محصول ، تغییر دادیم و این فیلدها را مقدار دهی اولیه کردیم . در این بخش میخواهیم کلاس سبدخرید را ادامه دهیم و توابع Add و Remove را پیاده سازی خواهیم کرد …
ایجاد کلاس ShoppingCart :
در فولدر Services که قبلا ایجاد کردیم یک کلاس تعریف کنید بنام ShoppingCart.cs . تمام عملیات درج و حذف و ویرایش آیتمهای سبدخرید ، در این کلاس تعریف می شوند .
ابتدا دو متغیر global در سطح کلاس بصورت زیر تعریف می کنیم :
private readonly StoreContext _db; private readonly string _cartId;
سپس سازنده کلاس را بصورت زیر تعریف میکنیم :
public ShoppingCart(HttpContextBase context) : this(context, new StoreContext()) { } public ShoppingCart(HttpContextBase httpContext , StoreContext storeContext) { _db = storeContext; _cartId = GetCartId(httpContext); }
تابع Add :
اولین تابعی که می خواهیم به کلاس سبدخرید اضافه کنیم Add می باشد .بدنه این تابع را به شکل زیر تعریف می کنیم :
public void Add(int id) { var product = _db.Products.SingleOrDefault(p => p.ProductId == id); if(product == null) { // TODO : Exception return; } var cartItem = _db.CartItems .SingleOrDefault(c => c.CartId == _cartId && c.ProductId == id ); if(cartItem != null) { cartItem.Count ++; } else { cartItem = new Models.CartItem(){ ProductId = id, CartId = _cartId, Count = 1 , DateCreated = DateTime.Now, }; _db.CartItems.Add(cartItem); } _db.SaveChanges(); }
توضیح : تابع Add ، id محصول را بعنوان پارامتر ورودی می گیرد . در شرط if اول ، بررسی می کند که اگر محصولی با این id در جدول محصولات موجود نباشد ، return میکند وگرنه به ادامه تابع می رود . در دستورات بعدی ، بررسی می شود که اگر سبد خرید از قبل ایجاد شده است ، تعداد آن محصول را یکی اضافه می کند و اگر سبد خرید جدید می باشد ، تعداد محصول را برابر عدد یک قرار می دهد و نیز productId محصول را برابر id و DateCreated را برابر زمان حال حاضر تعیین می کند . در نهایت این محصول را بعنوان یک رکورد از سبد خرید ثبت می کند و دیتابیس را آپدیت می کند .
تابع Remove :
تابع حذف دارای پارامتر ورودی int و خروجی int می باشد . پارامتر ورودی برای اینست که productId را می گیرد و آنرا حذف می کند . پارامتر خروجی به این دلیل بصورت عددی تعریف شده که ممکن است از محصول با id=productId چند آیتم در سبد خرید وجود داشته باشد و ما میخواهیم با فراخوانی تابع Remove ، فقط یکی از آنها را حذف کنیم . تعدادی که از آن محصول باقی می ماند را بصورت پارامتر خروجی این تابع در نظر گرفتیم .
public int Remove(int productId) { var cartItem = _db.CartItems .SingleOrDefault(c => c.CartId == _cartId && c.ProductId == productId); var ItemCount = 0; if(cartItem == null) { return ItemCount; } if (cartItem.Count > 1) { cartItem.Count–; ItemCount = cartItem.Count; } else { _db.CartItems.Remove(cartItem); } _db.SaveChanges(); return ItemCount; }
توضیح : مقدار خروجی این تابع ItemCount است . ابتدا مقدار پیش فرض صفر را دارد و سپس در شرط if بررسی می شود که اگر آیتمی در سبدخرید موجود نباشد ، عدد صفر را بعنوان خروجی برمیگرداند . اگر از آن محصول خاص در سبد خرید بیشتر از یک عدد موجود باشد یکی از تعداد آن کم می کند و آنرا return می کند . و در قسمت else اگر از آن محصول یک عدد در سبد خرید موجود باشد ، آن رکورد را از جدول cartItems حذف کرده و در نهایت دیتابیس را آپدیت می کند .
آموزش قدم به قدم ایجاد فروشگاه آنلاین با MVC – بخش سوم
Online Shop by MVC – Step by Step Tutorial – Part3
در بخش دوم از آموزش فروشگاه اینترنتی با ASP.NET MVC ، نحوه نمایش محصولات یک فهرست را بهمراه اکشن، view های لازم را آموزش دادیم و در نهایت کلاس سبدخرید را ایجاد کردیم و توابع Add و Remove را برای آن تعریف و پیاده سازی کردیم.
در بخش سوم از آموزش فروشگاه آنلاین با MVC ، سرفصل های زیر را در ادامه خواهیم داشت:
- تعریف کوکی برای CartId
- کنترولر ShoppingCart
کنترولر ShoppingCart و تست سبد خرید و ایجاد View برای سبدخرید و افزودن دکمه به Details - افزودن دکمه به Details
- سفارشات کاربران
ایجاد کلاس OrderDetail و ایجاد کلاس Order و اعمال تغییرات در StoreContext و عملیات Migration - ایجاد اکشن برای Checkout
ایجاد تابع Checkout در کلاس ShoppingCart.cs و تعریف اکشن Checkout در کنترولر سبدخرید و ایجاد View برای اکشن Checkout
تعریف کوکی برای 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 را با پارامتر 2 صدا زده ایم . با اجرای این آدرس ، پیام خطایی مبنی بر عدم وجود Index View نمایش داده می شود ( ولی نگران نباشید ، در مقاله بعد ویو را اضافه خواهیم کرد ! ) اکنون دیتابیس Management Studio را باز کنید و جدول cartItems را select کنید . با تصویر زیر روبرو خواهید شد :
و اگر آدرس فوق را مجددا اجرا کنید ، ستون Count در تصویر فوق برابر 2 خواهد شد .
حال می خواهیم حذف آیتم از سبدخرید را تست کنیم . بدین منظور ، آدرس زیر را پس از اجرای پروژه در نوار آدرس تایپ کرده و اینتر کنید :
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 Cart</h2> <hr /> <p class="btn btn-warning"> @Html.ActionLink("Check Out", "Checkout") </p> <hr /> <div id="update-message"></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> </td> <td> </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 به مراحل بعدی اجرای بعدی بروید وگرنه باید چک کنید که کدام فیلد را مطابق انتظار ، پر نکردید .
خب دوستان خسته نباشید . تا بدین جا در آموزش فروشگاه آنلاین با MVC ، بطور کلی مراحل زیر را انجام دادیم :
- طراحی مدل های Category , Product , Order , OrderDetail , CartItem
- طراحی و پیاده سازی سبد خرید (Shopping Cart)
- ثبت سفارش کاربر طبق سبد خرید نهایی شده
آموزش قدم به قدم ایجاد فروشگاه آنلاین با MVC – بخش چهارم
Online Shop by MVC – Step by Step Tutorial – Part4
در بخش سوم از آموزش پیاده سازی فروشگاه آنلاین با MVC کنترولر مربوط به سبد خرید را تکمیل کردیم و یک View ساده برای سبد خرید طراحی کردیم بخش سفارشات کاربران (Customers Orders) و Checkout را انجام دادیم. در این بخش قصد داریم نحوه اتصال فروشگاه اینترنتی خود را به یک درگاه آنلاین بین المللی آموزش دهیم.
سرفصل های بخش چهارم عبارتند از:
- اتصال به درگاه پرداخت آنلاین
تعریف کلاس PaymentResult و افزودن رفرنس BrainTree - اعمال تغییراتی در CheckoutViewModel
تغییرات تابع ProcessPayment و اعمال تغییراتی در فرم Checkout و پیاده سازی اکشن Complete
اتصال به درگاه پرداخت آنلاین :
در این سری آموزشی از درگاه BrainTree استفاده می کنیم . در تابع Checkout از کلاس ShoppingCart واقع در فولدر Services ، دستورات زیر را بنویسید :
var gateway = new PaymentGateway(); var result = gateway.ProcessPayment(model); if(result.Succeeded) { order.TransactionId = result.TransactionId; _db.Orders.Add(order); _db.CartItems.RemoveRange(items); // clear ShoppingCart _db.SaveChanges(); } return result;
توضیح : ابتدا از Braintree یک شئ می سازیم (Braintree در آینده توضیح داده خواهد شد) و مدل را به آن پاس میدهیم که این model شامل اطلاعات شخصی کاربر می باشد . اگر نتیجه موفقیت آمیز بود ، TransactionId در جدول order ذخیره می شود و یک سطر به جدول سفارشات اضافه و دیتابیس آپدیت می شود . در نهایت result را بعنوان خروجی می فرستیم .
تعریف کلاس PaymentResult :
یک کلاس بنام PaymentResult در فولدر Services ایجاد می کنیم و فیلدهای آنرا بصورت زیر تعریف می کنیم :
public class PaymentResult { public PaymentResult(string transactionId , bool success , string message) { TransactionId = transactionId; Succeeded = success; Message = message; } public string TransactionId { get; private set; } public bool Succeeded { get; private set; } public string Message { get; private set; } }
حالا در همین فولدر Services کلاس دیگری بنام IGateway که از نوع interface است :
public interface IGateway { PaymentResult ProcessPayment(CheckoutViewModel model); }
سپس کلاس دیگری بنام PaymentGateway در فولدر Services بسازید که در آن باید اینترفیس IGateway را پیاده سازی کنیم.
ابتدا این کلاس را بصورت زیر تعریف می کنیم :
public class PaymentGateway : IGateway { }
سپس مطابق تصویر زیر ، روی IGateway راست کلیک می کنیم و Implement Interface را انتخاب می کنیم :
نکته : در این مرحله باید تغییراتی را در تابع Checkout واقع در کلاس Shoppingcart اعمال کنیم . نوع خروجی این تابع را باید از object به PaymentResult تغییر کند . بصورت زیر :
public PaymentResult CheckOut(CheckoutViewModel model)
و همچنین بدنه تابع باید بصورت زیر تغییر کند :
if(!ModelState.IsValid) { return (View(model)); } var cart = new ShoppingCart(HttpContext); var result = cart.CheckOut(model); if(result.Succeeded) { TempData[“TransId”] = result.TransactionId; return RedirectToAction("Complete"); } ModelState.AddModelError(string.Empty,result.Message); return View(model);
در بخش قبل مراحل اولیه اتصال به درگاه پرداخت اینترنتی BrainTree را پیاده سازی کردیم و کلاس Payment Gateway را تعریف کردیم . در این بخش میخواهیم از طریق کنسول نوگت ، کتابخانه Braintree را به پروژه خود اضافه کنیم و تنظیمات آنرا انجام دهیم .
افزودن BrainTree :
روی فولدر References راست کلیک کنید و Manage NuGet Packages را انتخاب کنید . در پنجره باز شده ، عبارت BrainTree را سرچ کرده (مطابق شکل زیر) و BrainTree را نصب کنید :
سپس به وب سایت اصلی BrainTree مراجعه کنید . اکنون در این وب سایت ثبت نام (SignUp) کنید و روی دکمه Try SandBox کلیک کنید . به ایمیل شما لینکی ارسال می شود . روی این لینک کلیک کنید تا حساب شما فعال شود .
در کنترل پنل خود در منوی Account > My User را انتخاب کنید . سپس به قسمت API Keys Authorization بروید .
در این صفحه ، CSE Key را کپی کنید و در یک فایل notepad پیست کنید . بعدا لازم می شود!
سپس در باکس حاوی Public Key روی لینک View کلیک کنید و در این قسمت روی Java کلیک کنید و از لیست ظاهر شده .NET را انتخاب کنید (مطابق شکل زیر) :
علامت کپی در قسمت بالا-سمت راست این باکس مشاهده می کنید . روی آن کلیک کنید و آنرا بصورت زیر در پروژه خود و در فایل PaymentGateway پیست کنید :
private readonly BraintreeGateway _gateway = new BraintreeGateway { Environment = Braintree.Environment.SANDBOX, MerchantId = "xxxxxxxx", PublicKey = "xxxxxxxxxxxxx", PrivateKey = "xxxxxxxxxxxxxxxxxxxxxxxxx" };
نکته : دقت کنید که اطلاعات فوق بسیار حساس و خطرناک هستند و باید آنها را در web.config تعریف کنیم . ولی فعلا در اینجا تعریف کرده ایم .
تابع ProcessPayment واقع در کلاس PaymentGateway را مطابق زیر تعریف کنید :
public PaymentResult ProcessPayment(ViewModels.CheckoutViewModel model) { var request = new TransactionRequest() { Amount = model.Total, CreditCard = new TransactionCreditCardRequest { Number = "", CVV = "", ExpirationMonth = "", ExpirationYear = "", }, Options = new TransactionOptionsRequest() { SubmitForSettlement = true } }; var result = _gateway.Transaction.Sale(request); if(result.IsSuccess()) { return new PaymentResult(result.Target.Id,true,null) } return new PaymentResult(null,false,result.Message) }
در بخش قبل ، ابتدا توسط نوگت ، Braintree را به پروژه خود اضافه کردیم و سپس با مراجعه به وب سایت Braintree ، یک API-Key دریافت نمودیم و تنظیماتش را انجام دادیم . در این بخش ، که آخرین بخش از این سری آموزشی می باشد، میخواهیم تغییراتی در کلاس CheckoutViewModel و نیز ProcessPayment و فرم checkOut اعمال کنیم .
اعمال تغییراتی در CheckoutViewModel :
در این مرحله باید فیلدهای مربوط به کارت عابر بانک کاربر (البته بجز رمز دوم !) را در CheckoutViewMdoel اضافه کنیم :
[Required] public string CardNumber { get; set; } [Required] public string Cvv { get; set; } [Required] public string Month { get; set; } [Required] public string Year { get; set; }
تغییرات تابع ProcessPayment :
تابع فوق واقع در کلاس PaymentGateway.cs را بصورت زیر تغییر دهید و اطلاعات کارت بانکی را در آن درج کنید :
CreditCard = new TransactionCreditCardRequest { Number = model.CardNumber, CVV = model.Cvv, ExpirationMonth = model.Month, ExpirationYear = model.Year, }
اعمال تغییراتی در فرم Checkout :
برای افزودن امکان Encryption ، باید فایل جاوا اسکریپت زیر را به انتهای ویو و در بخش Scripts اضافه کنیم :
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
سپس در بالای فرم قابلیت نمایش پیامهای خطا را با افزودن دستور زیر به صفحه می دهیم :
@Html.ValidationSummary()
تگ فرم Checkout View را بصورت زیر تعریف می کنیم :
<form action="@Url.Action("checkout")" method="post" id="braintree-payment-form">
سپس سطرهای زیر را به آخر این فرم اضافه می نماییم :
<fieldset> <legend>Payment Information</legend> <p> <label>Card Number :</label> <input autocomplete="off" data-encrypted-name="CardNumber" name="CardNumber" size="20" type="text" /> </p> <p> <label>CVV 2 :</label> <input autocomplete="off" data-encrypted-name="Cvv" name="Cvv" size="3" type="text" /> </p> <p> <label>Expiration (MM/YYYY) :</label> <input name="Month" size="2" type="text" /> / <input name="Year" size="4" type="text" /> </p> </fieldset>
در نهایت در بخش Script انتهای همین صفحه ، کدهای زیر را وارد کنید :
@section Scripts { <script src="https://js.braintreegateway.com/v2/braintree.js"></script>;" <script> var braintree = braintree.create("aaaaaaaaaaabbbbbbbbbbbbbbbcccccccccccddddddddddddddeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffggggggggggggggggggggggghhhhhhhhhhhhhhhhhhhh11111111111222222222233333333333333 33333333344444444444444444555555555555555555555555555"); braintree.onSubmitEncryptForm("braintree-payment-form"); </script> <script src="https://js.braintreegateway.com/v2/braintree.js"></script> <script> var braintree = braintree.create("aaaaaaaaaaabbbbbbbbbbbbbbbcccccccccccddddddddddddddeeeeeeeeeeeeeeeeeee ffffffffffffffffffffffffggggggggggggggggggggggghhhhhhhhhhhhhhhhhhhh111111111112222222222333333333333 3333333333344444444444444444555555555555555555555555555"); braintree.onSubmitEncryptForm("braintree-payment-form"); </script> }
نکته : رشته طولانی که در دستورات فوق می بینید همان CSE Key می باشد که از سایت BrainTree کپی کرده اید .
پیاده سازی اکشن Complete :
در کنترولر ShoppingCart و در انتهای کنترولر ، اکشن Complete را بصورت زیر تعریف کنید :
public ActionResult Complete() { ViewBag.TransactionId = (string)TempData[“TransId”]; return View(); }
حالا روی اکشن راست کلیک کرده و Add View را انتخاب کنید . تنظیمات پیش فرض را بپذیرید و Add کنید .
در این صفحه می خواهیم از کاربر ، بابت خریدش تشکر کنیم و نیز Transaction ID را نمایش دهیم :
@{ ViewBag.Title = "Thanks !"; } <h2> Thanks For Shopping ! </h2> <hr /> <b>Your Transaction ID : @ViewBag.TransactionId</b>
حال برنامه را اجرا کنید . اگر سبدخرید خالی است چند محصول بصورت نمونه به آن اضافه کنید و در نهایت دکمه Checkout را بزنید . در فرمی که ظاهر می شود اطلاعات شخصی خود و نیز اطلاعات کارت را وارد نمایید و Next را بزنید .
نکته : اطلاعات نمونه زیر را برای تست فرآیند خرید وارد کنید :
Card Number : 4111111111111111 CVV 2 : 111 Expiration Date : 11/2015
اگر عملیات موفقیت آمیز باشد صفحه مطابق شکل زیر نمایش داده می شود و اطلاعات در جداول Order , OrderDetail ذخیره می شوند :
خب دوستان خسته نباشید ، اکنون توانستیم یک فروشگاه آنلاین را که دارای سبدخرید و پرداخت اینترنتی می باشد را پیاده سازی کنیم .
لطفا نظرات و سوالات خود را درباره سری آموزشی فروشگاه اینترنتی توسط ASP.NET MVC را به روش های زیر برای ما ارسال کنید:
- فرم ارسال دیدگاه پایین همین مقالات
- آدرس ایمیل contact@rahkarino.com
- فرم تماس با ما
دیدگاهتان را بنویسید