一步步打造一个简单的手动音量调节电商网站-书店(三)
本系列的开源代码库地址:https://github.com/liqingwen 2015/文.书店
《一步步打造一个简单的 MVC 电商网站 - BooksStore(一)》
《一步步打造一个简单的 MVC 电商网站 - BooksStore(二)》
《一步步打造一个简单的 MVC 电商网站 - BooksStore(三)》
《一步步打造一个简单的 MVC 电商网站 - BooksStore(四)》
简介
上一节我们完成了两个主要功能:添加到购物车和分类导航,这一节我们会完成整个购物车的流程,以及订单处理。
该系列主要功能与知识点如下:
分类、产品浏览、购物车、结算、CRUD(增删改查)管理、发邮件、分页、模型绑定、认证过滤器和单元测试等(预计剩余两篇,周三(因为周二不上班)先发布一篇)。
【备注】项目使用VS2015 C#6进行开发,有问题请发表在留言区哦,还有,页面长得比较丑,请见谅。
目录
完成购物车
订单结算
一、完成购物车
上一节其实已经完成了移除购物车和清空购物车的方法,只是尚未将可供用户操作的按钮放在页面区域。除了增加这两个按钮,也会在页面顶部的位置增加购物车的摘要(用于显示用户的购物总额)。
下面是上一节已经写好的CartController代码。
///摘要///购物车////摘要公共类购物车控制器:控制器{私有只读ibook存储库_图书存储库;公共购物车控制器(ibook repository book repository){ _ book repository=book repository;} ///摘要///首页////summary////param name=' return URL '/param////return/return public View结果Index(字符串返回URL){返回视图(new cardendexviewmodel(){ Cart=GetCart(),返回URL=返回URL });} ///摘要///添加到购物车////summary////param name=' id '/param///param name=' return URl '/param///returns/returns/返回public RedirectToRouteResult add to cart(int id,字符串返回URl){ var book=_ book repository .书籍。first or default(x=x . Id==Id);如果(书!=null) { GetCart().AddBook(book,1);}返回RedirectToAction('Index ',new { return URL });} ///摘要///从购物车移除////summary////param name=' id '/param///param name=' return URl '/param///return/return public redirecttoroutreault remove from cart(int id,string return URl){ var book=_ book repository .书籍。first or default(x=x . Id==Id);如果(书!=null) { GetCart().RemoveBook(图书);}返回RedirectToAction('Index ',new { return URL });} ///摘要///获取购物车////summary////returns/returns private Cart GetCart(){ var Cart=(Cart)Session[' Cart '];如果(推车!=null)返回购物车;Cart=新Cart();会话['购物车']=购物车;返回推车;} }1.加入移除书籍和清空购物车的功能
Index.cshtml
@模特文书店。webui。模特。cardindexviewmodel 2我的购物车/h2table class='table '和tr th书名/th价格/th数量/th总计/th/th/tr/the和tbody @foreach(模型中的定义变量项目。td@item.Book.Name/tdtd@item.Book.Price/td TD @ item。数量/td .预订。价格*项目。数量)。ToString(' C ')/TD TD @使用(Html).开始通知('从购物车中删除','购物车'){ @ Html .隐藏(“id”,项目书。Id) @Html .HiddenFor(x=x.ReturnUrl)输入类型='提交'值='-移除/}/TD/tr } tr TD/TD/TD总计:/td td@Model .推车。ComputeTotalValue().ToString(' C ')/TD TD @使用(Html .开始通知(“清除”、“购物车”){ @ Html .HiddenFor(x=x.ReturnUrl)输入类型='提交'值='清空购物车/} /td /tr /tbody/table【备注】@Html .隐藏(“id”,项目。图书编号)是用于生成隐藏的字段,如果直接使用@Html .HiddenFor(),生成的名字将会是项目。书。身份证,将和CartController中RemoveFromCart(int id,字符串返回)的参数不匹配。
显示的效果如下:
2.添加摘要:我们在购物车存放了许多东西,通过摘要,可以显示购物总额的缩略图,我们选择的位置在顶部右上角的一个比较显眼的位置进行显示它,当然,还需要有点击的跳转按钮方便显示所有的购物清单页面。
继续在CartController下新增一个行动,名为总结,返回值是一个分部视图:
///摘要///摘要////Summary////返回/返回公共部分视图结果Summary(){返回部分视图(GetCart());}对应的Summary.cshtml
@模特文书店。领域。实体。cart div class=' bookSummary '你的购物车:@模型ComputeTotalValue() span@Html .ActionLink('结算、"结帐"、"购物车",新的{ retunUrl=请求Url。PathAndQuery },null)/span/div对应的布局页_Layout.cshtml修改的地方为:
_Layout.cshtml
!DOCTYPE Html Html head meta name=' viewport ' content=' width=设备宽度-'/title@ViewBag.Title/title链接href='~/Contents/Site.css' rel='样式表/head dy div id=' header ' @ { Html .呈现操作("摘要"、"购物车");} div class='title '图书商城/div/div div id=' SiZe ' @ { Html .RenderAction('侧栏','导航');}/div div id=' content ' @ render body()/div/body/html添加了新的东西,css也要进行修改:
Site.css
正文{ } #标题,#内容,#侧边栏{ display : block } # header { background-color :绿色;边框-底部: 2px实心# 111;颜色:白色;} #标题,title { font-size : 1.5 empadding:5em } #侧边栏{左侧浮动:宽度: 8毫米;padding:3em } #内容{边框-左侧: 2px纯灰色;左边距: 10毫米;padding: 1em }。寻呼机{ text-align : right划水:5万;页边距-top : 1em;} .传呼机A { font-size : 1.1 em颜色: # 666划水0 .4em 0 .4em}。呼叫器A:hover {背景色-银色:} .寻呼机a .选中{底色: # 353535;颜色:白色;}.项目输入{右侧浮动:颜色:白色;背景-颜色:绿色;}.表{宽度: 100%;padd : 0;保证金: 0;} .表Helvetica阿里亚尔凡尔达纳,无衬线;color : # 4f 6b 72 border-right : 1px实心# C1DAD7边框-bottom: 1px实心# C1DAD7边框-top: 1px实心# C1DAD7字母间距2 xtext-transform :大写;文本-左对齐:padding: 6px 6px 6px 12px背景: #CAE8EA不重复;} .表td {边框-右侧: 1px实心# C1DAD7边框-bottom: 1px实心# C1DAD7背景# fffont-size : 14px;padd : 6px 6px 6px 12pxcolor 3360 # 4f 6b 72 }。表TD . alt { background : # f5Fafacolor : # 797268 }。表th.spec,td.spec {边框-左侧: 1px实心# C1DAD7}。bookSummary { width : 15%;向右浮动:保证金-前:位1.5%;}
二、订单结算
购物完毕就是结算页面了,这里的订单结算并不涉及支付接口的调用,只是使用邮件的形式进行通知而已。
这里,我设计结算的时候需要要求用户输入一些信息,如姓名、地址和邮箱等信息,在点击确定时我再将这些输入的信息与购物清单的信息从系统的邮箱发到你所输入的邮箱当中。一个比较直观的图:
1.在实体中添加一个域模型Contact.cs表示联系人的信息。
///摘要///联系信息////摘要公共类联系人{[必选(错误消息='姓名不能为空)]公共字符串名称{ get设置;}[必需(错误消息='地址不能为空)]公共字符串地址{ get设置;}[必需(错误消息='邮箱不能为空)][正则表达式(@ '( w([-].] w)* @ w([-].]w )* .w ([-.]w )*ww)',ErrorMessage='输入的邮箱地址不合法)]公共字符串电子邮件{ get设置;} }CartController.cs添加一个用于结算的操作:
///摘要///结算////summary///returns/returns public View result check(){ return View(新联系人());}Checkout.cshtml中的:
@模特文书店。领域。实体。联系方式@使用(Html .begin inform()){ div class=' error ' @ Html .ValidationSummary()/div姓名:@Html .TextBoxFor(x=x.Name)/div div地址:@Html .TextBoxFor(x=x。地址)/div邮箱:@Html .(x=x . Email)/div divinput类型=' submit '值='的文本框提交//div }/div这里使用的是模型校验,_Layout.cshtml布局页需要引入js:
script src=' http : ~/Scripts/jquery-1。10 .2 .js '/script script src=' http : ~/Scripts/jquery。验证。js '/script script src=' http : ~/Scripts/jquery。验证。联合国唐突。js '/脚本!DOCTYPE htmlhtmlhead元名称=' viewport '内容=' width=设备宽度'/title@ViewBag.Title/title链接href='~/Contents/Site.css' rel='样式表'/脚本src=' http : ~/Scripts/jquery-1。10 .2 .js /脚本src=' http : ~/Scripts/jquery。验证。js /脚本脚本src=' http : ~/Scripts/jquery。验证。js /不引人注目呈现操作("摘要"、"购物车");} div class='title '图书商城/div/div div id=' SiZe ' @ { Html .RenderAction('侧栏','导航');}/div div id=' content ' @ render body()/div/body/html尝试运行,会出现以下页面,如果信息不填的话会出现相关的错误提示:
2.接下来,要进入"提交"后的流程了。
现在还需要一个组件用于处理订单,创建一个用于订单处理的接口,和一个该接口的实现,再通过n项目进行两者的绑定:
///摘要///订单处理////摘要公共接口IOrderProcessor { ///摘要///处理订单////summary////param name=' Cart '/param///param name=' Contact '/param void流程订单(Cart Cart,Contact Contact);}建立一个实现该接口用于处理订单的实体类,这里并不是调用支付接口,而是简单通过基类库中的进行邮件的发送。
EmailOrderProcessor.cs:
///摘要///邮件订单处理器////摘要公共类EmailOrderProcessor : IOrderProcessor {///摘要///发送人////摘要公共静态类发件人{ ///摘要///账号////汇总公共静态字符串帐户='你的@ QQ。com///摘要///密码////汇总公共静态字符串密码=' XXX }////摘要///处理订单////summary////param name=' Cart '/param///param name=' Contact '/param public void流程订单(Cart Cart,Contact contact) { if (string .IsNullOrEmpty(联系人。电子邮件){抛出新的异常('电子邮件不能为空!');} var sb=new StringBuilder();foreach(购物车中的定义变量项目sb .AppendLine($' 《{item.Book.Name}》 :{item .预订。价格} * {物品。数量}={项目。预订。价格*项目。数量} ');}某人AppendLine($ '总额:{购物车。总和(x=x。数量* x。账面价格)} ');某人(某人的简写)AppendLine();某人(某人的简写)AppendLine($ '联系人:{联系人。姓名} {联系人。地址} ');//设置发件人,发件人需要与设置的邮件发送服务器的邮箱一致var fromAddr=新邮件地址(发件人。账户);var message=新邮件消息{ From=FromAddr };//设置收件人,可添加多个,添加方法与下面的一样消息。添加(联系人。电子邮件);//设置抄送人消息。抄送添加(发件人。账户);//设置邮件标题消息。主题='您的订单正在出库.';//设置邮件内容消息。身体=某人. ToString();//设置邮件发送服务器,服务器根据你使用的邮箱而不同,可以到相应的邮箱管理后台查看,下面是即时通信软件的var client=新建SmtpClient(' SMTP。QQ。com ',25){ 0凭据=新的网络凭据(发件人。帐户,发件人。密码),启用SsL=true };//设置发送人的邮箱账号和密码//启用ssl,也就是安全发送//发送邮件客户。发送(消息);}CartController也需要稍作调整:
还要在CartController中额外添加一个带[Http帖子]特性的名为检验方法:
///summary///settlement///summary///param name=' contact '/param///returns/returns[http post]公共视图结果签出(联系人联系人){if(!ModelState。IsValid)返回视图(联系人);var cart=GetCart();_orderProcessor。ProcessOrder(购物车、联系人);手推车。clear();返回视图(“谢谢”);}验证成功后会调用界面发送消息,清空已有购物车,然后跳转到指定的新查看页面:
用以下内容创建一个新的致谢网站:
谢谢
不要忘记添加一个绑定,并使用DI容器来绑定这两者:
启动页面并尝试效果:
似乎已经成功了:
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。