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














