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

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>

jiezhang

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

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>

}

运行:

tijiao

在为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("[email protected]");

            mailMsg.To.Add(new MailAddress("[email protected]"));

            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>

运行,点击提交显示:

huigu

管理员收到邮件:

order


至此,订单处理结束。

源码在这里

 

“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实现增删改查

你可能感兴趣的:(store)