ASP.NET MVC2 第五章Ⅲ
时间:2010-10-19 来源:T.337(Canon in D)
§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前台程序. 相对与亚马逊这还是远远不够的, 但是你已经有了一个可以通过分类, 分页显示的产品清单, 还有一个小小的购物车, 还有一个简单的收银程序.
高度分离的架构, 这意味这你可以很方便的进行更改和维护.在下一章中, 通过添加一个目录清单管理(包括增删改查功能)来完成整个项目.