欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一步步打造簡單的MVC電商網(wǎng)站BooksStore(3)

 更新時間:2017年04月06日 15:44:05   作者:反骨仔  
這篇文章主要和大家一起一步步打造一個簡單的MVC電商網(wǎng)站,MVC電商網(wǎng)站BooksStore第三篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(三)

本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(一)

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(二)

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(三)

一步步打造一個簡單的 MVC 電商網(wǎng)站 - BooksStore(四)

簡介

上一節(jié)我們完成了兩個主要功能:添加到購物車和分類導航,這一節(jié)我們會完成整個購物車的流程,以及訂單處理。

該系列主要功能與知識點如下:

分類、產(chǎn)品瀏覽、購物車、結(jié)算、CRUD(增刪改查) 管理、發(fā)郵件、分頁、模型綁定、認證過濾器和單元測試等(預計剩余兩篇,周三(因為周二不上班)先發(fā)布一篇)。

【備注】項目使用 VS2015 + C#6 進行開發(fā),有問題請發(fā)表在留言區(qū)哦,還有,頁面長得比較丑,請見諒。

目錄

完成購物車

訂單結(jié)算

一、完成購物車

上一節(jié)其實已經(jīng)完成了移除購物車和清空購物車的方法,只是尚未將可供用戶操作的按鈕放在頁面區(qū)域。除了增加這兩個按鈕,也會在頁面頂部的位置增加購物車的摘要(用于顯示用戶的購物總額)。

下面是上一節(jié)已經(jīng)寫好的 CartController 代碼。

/// <summary>
 /// 購物車
 /// </summary>
 public class CartController : Controller
 {
 private readonly IBookRepository _bookRepository;

 public CartController(IBookRepository bookRepository)
 {
  _bookRepository = bookRepository;
 }

 /// <summary>
 /// 首頁
 /// </summary>
 /// <param name="returnUrl"></param>
 /// <returns></returns>
 public ViewResult Index(string returnUrl)
 {
  return View(new CartIndexViewModel()
  {
  Cart = GetCart(),
  ReturnUrl = returnUrl
  });
 }

 /// <summary>
 /// 添加到購物車
 /// </summary>
 /// <param name="id"></param>
 /// <param name="returnUrl"></param>
 /// <returns></returns>
 public RedirectToRouteResult AddToCart(int id, string returnUrl)
 {
  var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

  if (book != null)
  {
  GetCart().AddBook(book, 1);
  }

  return RedirectToAction("Index", new { returnUrl });
 }

 /// <summary>
 /// 從購物車移除
 /// </summary>
 /// <param name="id"></param>
 /// <param name="returnUrl"></param>
 /// <returns></returns>
 public RedirectToRouteResult RemoveFromCart(int id, string returnUrl)
 {
  var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

  if (book != null)
  {
  GetCart().RemoveBook(book);
  }

  return RedirectToAction("Index", new { returnUrl });
 }

 /// <summary>
 /// 獲取購物車
 /// </summary>
 /// <returns></returns>
 private Cart GetCart()
 {
  var cart = (Cart)Session["Cart"];
  if (cart != null) return cart;

  cart = new Cart();
  Session["Cart"] = cart;

  return cart;
 }
 }

1.加入移除書籍和清空購物車的功能

Index.cshtml

@model Wen.BooksStore.WebUI.Models.CartIndexViewModel

<h2>我的購物車</h2>

<table class="table">
 <thead>
 <tr>
  <th>書名</th>
  <th>價格</th>
  <th>數(shù)量</th>
  <th>總計</th>
  <th> </th>
 </tr>
 </thead>
 <tbody>
 @foreach (var item in Model.Cart.GetCartItems)
 {
  <tr>
  <td>@item.Book.Name</td>
  <td>@item.Book.Price</td>
  <td>@item.Quantity</td>
  <td>@((item.Book.Price * item.Quantity).ToString("C"))</td>
  <td>
   @using (Html.BeginForm("RemoveFromCart", "Cart"))
   {
   @Html.Hidden("id", item.Book.Id)
   @Html.HiddenFor(x => x.ReturnUrl)
   <input type="submit" value="- 移除" />
   }
  </td>
  </tr>
 }
 <tr>
  <td> </td>
  <td> </td>
  <td>總計:</td>
  <td>@Model.Cart.ComputeTotalValue().ToString("C")</td>
  <td>
  @using (Html.BeginForm("Clear", "Cart"))
  {
   @Html.HiddenFor(x => x.ReturnUrl)
   <input type="submit" value="清空購物車" />
  }
  </td>
 </tr>
 </tbody>

</table>

【備注】@Html.Hidden("id", item.Book.Id) 是用于生成隱藏的字段,如果直接使用@Html.HiddenFor(),生成的 name 將會是 item.Book.Id ,將和 CartController 中 RemoveFromCart(int id, string return) 的參數(shù)不匹配。

顯示的效果如下:

2.添加摘要:我們在購物車存放了許多東西,通過摘要,可以顯示購物總額的縮略圖,我們選擇的位置在頂部右上角的一個比較顯眼的位置進行顯示它,當然,還需要有點擊的跳轉(zhuǎn)按鈕方便顯示所有的購物清單頁面。

繼續(xù)在 CartController 下新增一個 Action,名為 Summary,返回值是一個分部視圖:

/// <summary>
 /// 摘要
 /// </summary>
 /// <returns></returns>
 public PartialViewResult Summary()
 {
  return PartialView(GetCart());
 }

對應的Summary.cshtml

@model Wen.BooksStore.Domain.Entities.Cart

<div class="bookSummary">
 你的購物車:@Model.ComputeTotalValue() 
 <span>@Html.ActionLink("結(jié)算", "Checkout", "Cart", new { retunUrl = Request.Url.PathAndQuery }, null)</span>
</div>

對應的布局頁_Layout.cshtml 修改的地方為:

_Layout.cshtml

<!DOCTYPE html>

<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>@ViewBag.Title</title>
 <link href="~/Contents/Site.css" rel="stylesheet" />
</head>
<body>
 <div id="header">
 @{ Html.RenderAction("Summary", "Cart");}
 <div class="title">圖書商城</div>
 </div>
 <div id="sideBar">
 @{ Html.RenderAction("Sidebar", "Nav"); }
 </div>
 <div id="content">
 @RenderBody()
 </div>
</body>
</html>

添加了新的東西,css 也要進行修改:

Site.css

body {
}

#header, #content, #sideBar {
 display: block;
}

#header {
 background-color: green;
 border-bottom: 2px solid #111;
 color: White;
}

#header, .title {
 font-size: 1.5em;
 padding: .5em;
}

#sideBar {
 float: left;
 width: 8em;
 padding: .3em;
}

#content {
 border-left: 2px solid gray;
 margin-left: 10em;
 padding: 1em;
}

.pager {
 text-align: right;
 padding: .5em 0 0 0;
 margin-top: 1em;
}

 .pager A {
 font-size: 1.1em;
 color: #666;
 padding: 0 .4em 0 .4em;
 }

 .pager A:hover {
  background-color: Silver;
 }

 .pager A.selected {
  background-color: #353535;
  color: White;
 }

.item input {
 float: right;
 color: White;
 background-color: green;
}

.table {
 width: 100%;
 padding: 0;
 margin: 0;
}

 .table th {
 font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
 color: #4f6b72;
 border-right: 1px solid #C1DAD7;
 border-bottom: 1px solid #C1DAD7;
 border-top: 1px solid #C1DAD7;
 letter-spacing: 2px;
 text-transform: uppercase;
 text-align: left;
 padding: 6px 6px 6px 12px;
 background: #CAE8EA no-repeat;
 }

 .table td {
 border-right: 1px solid #C1DAD7;
 border-bottom: 1px solid #C1DAD7;
 background: #fff;
 font-size: 14px;
 padding: 6px 6px 6px 12px;
 color: #4f6b72;
 }

 .table td.alt {
  background: #F5FAFA;
  color: #797268;
 }

 .table th.spec, td.spec {
 border-left: 1px solid #C1DAD7;
 }

.bookSummary {
 width: 15%;
 float: right;
 margin-top: 1.5%;
}

二、訂單結(jié)算

購物完畢就是結(jié)算頁面了,這里的訂單結(jié)算并不涉及支付接口的調(diào)用,只是使用郵件的形式進行通知而已。

這里,我設(shè)計結(jié)算的時候需要要求用戶輸入一些信息,如姓名、地址和郵箱等信息,在點擊確定時我再將這些輸入的信息與購物清單的信息從系統(tǒng)的郵箱發(fā)到你所輸入的郵箱當中。一個比較直觀的圖:

1.在 Entities 中添加一個域模型 Contact.cs 表示聯(lián)系人的信息。

/// <summary>
 /// 聯(lián)系信息
 /// </summary>
 public class Contact
 {
 [Required(ErrorMessage = "姓名不能為空")]
 public string Name { get; set; }

 [Required(ErrorMessage = "地址不能為空")]
 public string Address { get; set; }

 [Required(ErrorMessage = "郵箱不能為空")]
 [RegularExpression(@"(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*\w\w)", ErrorMessage = "輸入的郵箱地址不合法")]
 public string Email { get; set; }
 }

CartController.cs 添加一個用于結(jié)算的 Action:

/// <summary>
 /// 結(jié)算
 /// </summary>
 /// <returns></returns>
 public ViewResult Checkout()
 {
  return View(new Contact());
 }

Checkout.cshtml 中的:

@model Wen.BooksStore.Domain.Entities.Contact

<div>
 @using (Html.BeginForm())
 {
 <div class="error">@Html.ValidationSummary()</div>
 <div>姓名: @Html.TextBoxFor(x => x.Name)</div>
 <div>地址: @Html.TextBoxFor(x => x.Address)</div>
 <div>郵箱: @Html.TextBoxFor(x => x.Email)</div>
 <div><input type="submit" value="提交" /></div>
 }

</div>

這里使用的是模型校驗,_Layout.cshtml 布局頁需要引入js:

<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>


<!DOCTYPE html>

<html>
<head>
 <meta name="viewport" content="width=device-width" />
 <title>@ViewBag.Title</title>
 <link href="~/Contents/Site.css" rel="stylesheet" />
 <script src="~/Scripts/jquery-1.10.2.js"></script>
 <script src="~/Scripts/jquery.validate.js"></script>
 <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
</head>
<body>
 <div id="header">
 @{ Html.RenderAction("Summary", "Cart");}
 <div class="title">圖書商城</div>
 </div>
 <div id="sideBar">
 @{ Html.RenderAction("Sidebar", "Nav"); }
 </div>
 <div id="content">
 @RenderBody()
 </div>
</body>
</html>

嘗試運行,會出現(xiàn)以下頁面,如果信息不填的話會出現(xiàn)相關(guān)的錯誤提示:

2.接下來,要進入“提交”后的流程了。

現(xiàn)在還需要一個組件用于處理訂單,創(chuàng)建一個用于訂單處理的接口,和一個該接口的實現(xiàn),再通過 Ninject 進行兩者的綁定:

/// <summary>
 /// 訂單處理
 /// </summary>
 public interface IOrderProcessor
 {
 /// <summary>
 /// 處理訂單
 /// </summary>
 /// <param name="cart"></param>
 /// <param name="contact"></param>
 void ProcessOrder(Cart cart, Contact contact);
 }

建立一個實現(xiàn)該接口用于處理訂單的實體類,這里并不是調(diào)用支付接口,而是簡單通過 BCL 中的進行郵件的發(fā)送。

EmailOrderProcessor.cs:

/// <summary>
 /// 郵件訂單處理器
 /// </summary>
 public class EmailOrderProcessor : IOrderProcessor
 {
 /// <summary>
 /// 發(fā)送人
 /// </summary>
 public static class Sender
 {
  /// <summary>
  /// 賬號
  /// </summary>
  public static string Account = "你的@qq.com";

  /// <summary>
  /// 密碼
  /// </summary>
  public static string Password = "xxx";
 }

 /// <summary>
 /// 處理訂單
 /// </summary>
 /// <param name="cart"></param>
 /// <param name="contact"></param>
 public void ProcessOrder(Cart cart, Contact contact)
 {
  if (string.IsNullOrEmpty(contact.Email))
  {
  throw new Exception("Email 不能為空!");
  }

  var sb = new StringBuilder();
  foreach (var item in cart.GetCartItems)
  {
  sb.AppendLine($"《{item.Book.Name}》:{item.Book.Price} * {item.Quantity} = {item.Book.Price * item.Quantity}");
  }

  sb.AppendLine($"總額:{cart.GetCartItems.Sum(x => x.Quantity * x.Book.Price)}");
  sb.AppendLine();
  sb.AppendLine($"聯(lián)系人:{contact.Name} {contact.Address}");

  //設(shè)置發(fā)件人,發(fā)件人需要與設(shè)置的郵件發(fā)送服務器的郵箱一致
  var fromAddr = new MailAddress(Sender.Account);
  var message = new MailMessage { From = fromAddr };

  //設(shè)置收件人,可添加多個,添加方法與下面的一樣
  message.To.Add(contact.Email);
  //設(shè)置抄送人
  message.CC.Add(Sender.Account);
  //設(shè)置郵件標題
  message.Subject = "您的訂單正在出庫...";
  //設(shè)置郵件內(nèi)容
  message.Body = sb.ToString();
  //設(shè)置郵件發(fā)送服務器,服務器根據(jù)你使用的郵箱而不同,可以到相應的 郵箱管理后臺查看,下面是QQ的

  var client = new SmtpClient("smtp.qq.com", 25)
  {
  Credentials = new NetworkCredential(Sender.Account, Sender.Password),
  EnableSsl = true
  };

  //設(shè)置發(fā)送人的郵箱賬號和密碼
  //啟用ssl,也就是安全發(fā)送
  //發(fā)送郵件
  client.Send(message);
 }

CartController 也需要稍作調(diào)整:

還要在 CartController 中額外添加一個帶[HttPost] 特性的名為 Checkout 方法:

/// <summary>
 /// 結(jié)算
 /// </summary>
 /// <param name="contact"></param>
 /// <returns></returns>
 [HttpPost]
 public ViewResult Checkout(Contact contact)
 {
  if (!ModelState.IsValid)
  return View(contact);

  var cart = GetCart();
  _orderProcessor.ProcessOrder(cart, contact);
  cart.Clear();
  return View("Thanks");
 }

當校驗成功時,會調(diào)用接口發(fā)一條信息,并且清空已有的購物車,然后跳轉(zhuǎn)到指定的一個新視圖頁:

新建 Thanks.cshtml,內(nèi)容如下:

Thanks

別忘了添加綁定哦,使用 DI 容器將兩者進行綁定:

啟動頁面,試試效果吧:

看來,好像成功了哦:

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論