§5.3 Submitting Orders
In this product development cycle, SportsStore will just send details of completed orders to the site administrator by e-mail. It need not store the order data in your database. However, that plan might change in the future, so to make this behavior easily changeable, you’ll implement an abstract order submission service, IOrderSubmitter.
§5.3.1 Enhancing the Domain Model
Get started by implementing a model class for shipping details. Add a new class to your SportsStore.Domain project’s Entities folder,
namespace SportsStore.Domain.Entities { public class ShippingDetails { [Required(ErrorMessage = "Please enter a name")] public string Name { get; set; } [Required(ErrorMessage = "Please enter the first address line")] public string Line1 { get; set; } public string Line2 { get; set; } public string Line3 { get; set; } [Required(ErrorMessage = "Please enter a city name")] public string City { get; set; } [Required(ErrorMessage = "Please enter a state name")] public string State { get; set; } public string Zip { get; set; } [Required(ErrorMessage = "Please enter a country name")] public string Country { get; set; } public bool GiftWrap { get; set; } } }Remember to add System.ComponentModel.DataAnnotations assembly.
§5.3.2 Adding the “Check Out Now” Button
Returning to the cart’s Index view, add a button that navigates to an action called CheckOut
<p align="center" class="actionButtons"> <a href="<%= Model.ReturnUrl %>">Continue shopping</a> <%= Html.ActionLink("Check out now", "CheckOut") %> </p>
§5.3.3 Prompting the Customer for Shipping Details
Add a new action, CheckOut, to CartController.
public ViewResult CheckOut() { return View(new ShippingDetails()); }And add a view for the action.update the code as follows:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>CheckOut</h2> Please enter your details, and we'll ship your goods right away! <% using(Html.BeginForm()) { %> <%=Html.ValidationSummary() %> <h3>Ship to</h3> <div>Name: <%= Html.EditorFor(x => x.Name) %></div> <h3>Address</h3> <div>Line 1: <%= Html.EditorFor(x => x.Line1) %></div> <div>Line 2: <%= Html.EditorFor(x => x.Line2) %></div> <div>Line 3: <%= Html.EditorFor(x => x.Line3) %></div> <div>City: <%= Html.EditorFor(x => x.City) %></div> <div>State: <%= Html.EditorFor(x => x.State) %></div> <div>Zip: <%= Html.EditorFor(x => x.Zip) %></div> <div>Country: <%= Html.EditorFor(x => x.Country)%></div> <h3>Options</h3> <label> <%= Html.EditorFor(x => x.GiftWrap) %> Gift wrap these items </label> <p align="center"><input type="submit" value="Complete order" /></p> <% } %> </asp:Content>在这个视图中, 我们为每个输入控件使用了Html.EditorFor() 辅助类. 这是templated view helper的一个例子. 使用它的想法是明确指定你要的HTML元素.(比如使用Html.TextBoxFor).
§5.3.4 Defining an Order Submitter DI Component
现在, 如果用户想把他们的请求单信息发来, 你可以使用action把信息通过STMP邮出去. 但是我们这里要做个接口, 方便更多情况的发生.
namespace SportsStore.Domain.Services { public interface IOrderSubmitter { void SubmitOrder(Cart cart, ShippingDetails shippingDetails); } }
§5.3.5 Completing CartController
为了完成CartController, 我们要建立它对IOrderSubmitter 依赖. 更新CartController 的构造器
namespace SportsStore.WebUI.Controllers { public class CartController : Controller { private IProductsRepository productsRepository; private IOrderSubmitter orderSubmitter; public CartController(IProductsRepository productsRepository, IOrderSubmitter orderSubmitter) { this.productsRepository = productsRepository; this.orderSubmitter = orderSubmitter; } } }为了实现CheckOut的POST action. 我们要继续给CartController 添加一个方法
[HttpPost] public ActionResult CheckOut(Cart cart, ShippingDetails shippingDetails) { if (cart.Lines.Count == 0) ModelState.AddModelError("Cart", "Sorry, your cart is empty!"); if (ModelState.IsValid) { orderSubmitter.SubmitOrder(cart, shippingDetails); cart.Clear(); return View("Completed"); } else // Something was invalid return View(shippingDetails); }
§5.3.6 Adding a Fake Order Submitter
这里, 我们还要添加一个CartController’的继承类FakeOrderSubmitter:
namespace SportsStore.Domain.Services { public class FakeOrderSubmitter : IOrderSubmitter { public void SubmitOrder(Cart cart, ShippingDetails shippingDetails) { } } }并且在配置模型NinjectControllerFactory中注册
private class SportsStoreServices : NinjectModule { public override void Load() { Bind<IOrderSubmitter>() .To<FakeOrderSubmitter>(); } }
§5.3.7 Displaying Validation Errors
你可能已经发现了, 我们如果输入错误是看不到为什么的. 所以为了验证我们输入的是否正确, 我们要在CheckOut.aspx 视图中加入Html.ValidationSummary()验证
<% using(Html.BeginForm()) { %> <%: Html.ValidationSummary() %> ... 其他地方没有更改 ...这样当你没有通过验证的时候, 就会出现下面的图
§5.3.8 Displaying a “Thanks for Your Order” Screen
为了把这个"结账"的过程结束, 我们还要添加一个Completed 的视图. 进入SportsStore.WebUI 工程的 /Views/Cart 文件夹. 右击添加view, partial和强类型不要打勾.
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> SportsStore : Order Submitted </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2>Thanks</h2> Thanks for placing your order. We'll ship your goods as soon as possible. </asp:Content>这样, 当你把整个程序走完的时候, 会出现下面这个感谢界面
§5.3.9 Implementing EmailOrderSubmitter
这里讲到的是, 实现一个Email订单的提交. 不做论述
§5.4 Summary
你已经大概的完成了SportsStore前台程序. 相对与亚马逊这还是远远不够的, 但是你已经有了一个可以通过分类, 分页显示的产品清单, 还有一个小小的购物车, 还有一个简单的收银程序.
高度分离的架构, 这意味这你可以很方便的进行更改和维护.在下一章中, 通过添加一个目录清单管理(包括增删改查功能)来完成整个项目.
作者:石世特
出处:http://www.cnblogs.com/TivonStone/
希望本文对你有所帮助,想转随便转,心情好的话给我的文章留个链接.o(. .)o