SportsStore是《精通ASP.NET MVC3框架(第三版)》中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器、URL优化、导航、分页、购物车、订单、产品管理、图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离。本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能。

本篇为系列第七篇,包括:

■ 9、实现订单提交

9、实现订单提交

首先在购物车显示页面Cart/Index.cshtml中,添加结账按钮:

@model MySportsStore.WebUI.Models.CartIndexViewModel

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
} <table width="50%" align="left">
<thead>
<tr>
<th align="left">产品名称</th>
<th align="center">数量</th>
<th align="right">单价</th>
<th align="right">小计</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var line in Model.Cart.Lines)
{
<tr>
<td align="left">@line.Product.Name</td>
<td align="center">@line.Quantity</td>
<td align="right">@line.Product.Price.ToString("c")</td>
<td align="right">@((line.Quantity * line.Product.Price).ToString("c"))</td>
<td>
@using (Html.BeginForm("RemoveFromCart", "Cart"))
{
@Html.Hidden("Id", line.Product.Id)
@Html.HiddenFor(x => x.ReturnUrl)
<input class="actionButtons" type="submit" value="移除"/>
}
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="3" align="right">总计:</td>
<td align="right">@Model.Cart.ComputeTotalValue().ToString("c")</td>
</tr>
</tfoot>
</table>
<p align="left" class="actionButtons" style="width: 100%;clear: both">
<a href="@Model.ReturnUrl">继续购物</a>
@Html.ActionLink("结账","CheckOut")
</p>

点击结账,跳转到一个视图页面,填写必要的联系方式等信息,其对应的模型为:

using System.ComponentModel.DataAnnotations;

namespace MySportsStore.Model
{
public class ShippingDetail
{
[Required(ErrorMessage = "必填")]
[Display(Name = "姓名")]
public string Name { get; set; } [Required(ErrorMessage = "必填")]
[Display(Name = "地址")]
public string Line { get; set; }
}
}

订单提交页Cart/CheckOUt.cshtml:

@model MySportsStore.Model.ShippingDetail

@{
ViewBag.Title = "CheckOut";
Layout = "~/Views/Shared/_Layout.cshtml";
} <h2>填写地址等信息</h2> @using (Html.BeginForm())
{
@Html.LabelFor(m => m.Name)
@Html.EditorFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)
<br/><br/>
@Html.LabelFor(m => m.Line)
@Html.EditorFor(m => m.Line)
@Html.ValidationMessageFor(m => m.Line) <p align="center">
<input class="actionButtons" type="submit" value="提交订单"/>
</p>
}

运行:

在为Cart控制器添加处理订单的方法之前,我们首先定义一个处理订单的接口:

using MySportsStore.Model;
using MySportsStore.WebUI.Models; namespace MySportsStore.WebUI.Abstract
{
public interface IOrderProcessor
{
void ProcessOrder(Cart cart, ShippingDetail shippingDetail); }
}

假设,我们希望在接到订单时发邮件给管理员,创建一个实现IOrderProcessor的类:

using System.Net;
using System.Net.Mail;
using System.Text;
using MySportsStore.WebUI.Abstract; namespace MySportsStore.WebUI.Concrete
{
public class EmailOrderProcessor : IOrderProcessor
{
public void ProcessOrder(Models.Cart cart, Model.ShippingDetail shippingDetail)
{
MailMessage mailMsg = new MailMessage();
mailMsg.From = new MailAddress("qdjjx9441@sina.com");
mailMsg.To.Add(new MailAddress("764190362@qq.com"));
mailMsg.Subject = "新订单"; //邮件内容主体
StringBuilder body = new StringBuilder();
body.AppendLine("接收到一个新订单:");
body.AppendLine("<br />");
body.AppendLine("订购商品包括:");
body.AppendLine("<br />");
foreach (var line in cart.Lines)
{
var subTotal = line.Product.Price * line.Quantity;
body.AppendFormat("{0}*{1}(小计:{2:c})", line.Quantity, line.Product.Name, subTotal);
body.AppendLine("<br />");
}
body.AppendFormat("总计:{0:c}", cart.ComputeTotalValue());
body.AppendLine("<br />");
body.AppendLine("收货人信息:");
body.AppendLine(shippingDetail.Name);
body.AppendLine(shippingDetail.Line);
body.AppendLine("<br />"); mailMsg.Body = body.ToString();
mailMsg.IsBodyHtml = true;
SmtpClient smtpClient = new SmtpClient("smtp.sina.com");
smtpClient.Credentials = new NetworkCredential("some username", "some password"); smtpClient.Send(mailMsg);
}
}
}

把接口IOrderProcessor和实现类EmailOrderProcessor交给Ninject来实现,以便依赖注入:

private void AddBindings()
{
ninjectKernel.Bind<IProductService>().To<ProductService>();
ninjectKernel.Bind<IOrderProcessor>().To<EmailOrderProcessor>();
}

现在可以在Cart控制器中添加处理订单的逻辑:

using System.Linq;
using System.Web.Mvc;
using MySportsStore.IBLL;
using MySportsStore.Model;
using MySportsStore.WebUI.Abstract;
using MySportsStore.WebUI.Models;
using Ninject; namespace MySportsStore.WebUI.Controllers
{
public class CartController : BaseController
{
[Inject]
public IProductService ProductService { get; set; } [Inject]
public IOrderProcessor OrderProcessor { get; set; } public CartController()
{
this.AddDisposableObject(ProductService);
this.AddDisposableObject(OrderProcessor);
} public ViewResult CheckOut()
{
return View(new ShippingDetail());
} [HttpPost]
public ViewResult CheckOut(Cart cart, ShippingDetail shippingDetail)
{
if (cart.Lines.Count() == 0)
{
ModelState.AddModelError("","购物车为空");
}
if (ModelState.IsValid)
{
OrderProcessor.ProcessOrder(cart, shippingDetail);
cart.Clear();
return View("Completed");
}
else
{
return View(shippingDetail);
}
}
...... }
}

订单提交成功后,显示Cart/Completed.cshtml视图:

@{
ViewBag.Title = "Completed";
Layout = "~/Views/Shared/_Layout.cshtml";
} <h2>谢谢惠顾~~</h2>

运行,点击提交显示:

管理员收到邮件:

至此,订单处理结束。

源码在这里

“MVC项目实践,在三层架构下实现SportsStore”系列包括:

MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构

MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

MVC项目实践,在三层架构下实现SportsStore-04,实现分页

MVC项目实践,在三层架构下实现SportsStore-05,实现导航

MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交

MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

MVC项目实践,在三层架构下实现SportsStore-10,连接字符串的加密和解密

MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查

MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交的更多相关文章

  1. MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构

    在"MVC项目实践,在三层架构下实现SportsStore-02,DbSession层.BLL层"一文的评论中,博友浪花一朵朵建议用类图来理解本项目的三层架构.于是就有了本篇: I ...

  2. MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  3. MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  4. MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  5. MVC项目实践,在三层架构下实现SportsStore-04,实现分页

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  6. MVC项目实践,在三层架构下实现SportsStore-05,实现导航

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  7. MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  8. MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

    SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...

  9. MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

    ASP.NET Web API和WCF都体现了REST软件架构风格.在REST中,把一切数据视为资源,所以也是一种面向资源的架构风格.所有的资源都可以通过URI来唯一标识,通过对资源的HTTP操作(G ...

随机推荐

  1. Leetcode | Parentheses 相关

    Generate Parentheses Given n pairs of parentheses, write a function to generate all combinations of ...

  2. Ubuntu基础命令

    显示历史命令的时间戳 echo 'HISTTIMEFORMAT="%F %T "' >> ~/.bashrc   解压文件/打包文件夹 tar -zxvf folder ...

  3. SwfUpload学习记录

    参考资料: SWFUpload 2.5.0版 官方说明文档 中文翻译版 了解SWFUpload 多文件上传配置详解 WEB版一次选择多个文件进行批量上传(swfupload)的解决方案 jQuery轻 ...

  4. BNF 巴科斯范式

    BNF 巴科斯范式(BNF: Backus-Naur Form 的缩写)是由 John Backus 和 Peter Naur 首先引入的用来描述计算机语言语法的符号集.现在,几乎每一位新编程语言书籍 ...

  5. 优秀而又实用的PHP工具集锦

    优秀而又实用的PHP工具集锦   浏览:1141 发布日期:2013/09/04 分类:技术分享 PHP是目前实用最为广泛的服务器端开源脚本语言之一,很多优秀的开源程序都是基于PHP构建的,比如大名鼎 ...

  6. PHP Console工具使用分享

    PHP Console工具使用分享 http://www.open-open.com/lib/view/open1416193590414.html 您的评价:       不错  收藏该经验     ...

  7. Why Stored Procedures?

    http://www.w3resource.com/mysql/mysql-procedure.php Stored procedures are fast. MySQL server takes s ...

  8. Spark 2.0

    Apache Spark 2.0: Faster, Easier, and Smarter http://blog.madhukaraphatak.com/categories/spark-two/ ...

  9. VS C++ 从一个窗口创建另一个窗口

    一.在stdafx.h文件中,添加: #include "Form2.h" / stdafx.h : 标准系统包含文件的包含文件, // 或是经常使用但不常更改的 // 特定于项目 ...

  10. 三 mybatis typeAlias(别名)使用和resultMap使用

     1.MyBatis提供的typeAlias