[.NET] 一步步制作二个轻易易行的 MVC 电商网站 – BooksStore(3)

by admin on 2019年4月21日

  《[一步步成立一个简便的 MVC 电商网址

BooksStore(三)](http://www.cnblogs.com/liqingwen/p/6652564.html)》(发布时间:2017-04-01)

不过大学住宿和高级学校从前的止宿给人的认为是差别等的,大学在此在此以前宿舍的人脉关系很轻,可有可无,能遇上心仪的好情人那是再好不过,碰不到也没涉及,因为大家的好爱人范围是在全班,宿舍只是贰个小天地罢了。

  《[一步步创设一个简约的 MVC 电商网址

BooksStore(四)](http://www.cnblogs.com/liqingwen/p/6658975.html%20)》(发布时间:2017-04-05)

 

文 葬心YX

1、完结购物车

  上一节其实早就做到了移除购物车和清空购物车的形式,只是未有将可供用户操作的开关放在页面区域。除了扩大那多少个开关,也会在页面顶部的地点扩大购物车的摘要(用于显示用户的购物资总公司额)。

  上边是上一节已经写好的 CartController 代码。

图片 1图片 2

/// <summary>
    /// 购物车
    /// </summary>
    public class CartController : Controller
    {
        private readonly IBookRepository _bookRepository;

        public CartController(IBookRepository bookRepository)
        {
            _bookRepository = bookRepository;
        }

        /// <summary>
        /// 首页
        /// </summary>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ViewResult Index(string returnUrl)
        {
            return View(new CartIndexViewModel()
            {
                Cart = GetCart(),
                ReturnUrl = returnUrl
            });
        }

        /// <summary>
        /// 添加到购物车
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public RedirectToRouteResult AddToCart(int id, string returnUrl)
        {
            var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

            if (book != null)
            {
                GetCart().AddBook(book, 1);
            }

            return RedirectToAction("Index", new { returnUrl });
        }

        /// <summary>
        /// 从购物车移除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public RedirectToRouteResult RemoveFromCart(int id, string returnUrl)
        {
            var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

            if (book != null)
            {
                GetCart().RemoveBook(book);
            }

            return RedirectToAction("Index", new { returnUrl });
        }

        /// <summary>
        /// 获取购物车
        /// </summary>
        /// <returns></returns>
        private Cart GetCart()
        {
            var cart = (Cart)Session["Cart"];
            if (cart != null) return cart;

            cart = new Cart();
            Session["Cart"] = cart;

            return cart;
        }
    }

CartController.cs

 

  一.加入移除书籍和清空购物车的法力

图片 3

图片 4图片 5

@model Wen.BooksStore.WebUI.Models.CartIndexViewModel

<h2>我的购物车</h2>

<table class="table">
    <thead>
        <tr>
            <th>书名</th>
            <th>价格</th>
            <th>数量</th>
            <th>总计</th>
            <th> </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Cart.GetCartItems)
        {
            <tr>
                <td>@item.Book.Name</td>
                <td>@item.Book.Price</td>
                <td>@item.Quantity</td>
                <td>@((item.Book.Price * item.Quantity).ToString("C"))</td>
                <td>
                    @using (Html.BeginForm("RemoveFromCart", "Cart"))
                    {
                        @Html.Hidden("id", item.Book.Id)
                        @Html.HiddenFor(x => x.ReturnUrl)
                        <input type="submit" value="- 移除" />
                    }
                </td>
            </tr>
        }
        <tr>
            <td> </td>
            <td> </td>
            <td>总计:</td>
            <td>@Model.Cart.ComputeTotalValue().ToString("C")</td>
            <td>
                @using (Html.BeginForm("Clear", "Cart"))
                {
                    @Html.HiddenFor(x => x.ReturnUrl)
                    <input type="submit" value="清空购物车" />
                }
            </td>
        </tr>
    </tbody>

</table>

Index.cshtml

  【备注】@Html.Hidden(“id”, item.Book.Id)
是用于转移隐藏的字段,若是直接使用 @Html.HiddenFor(),生成的 name 将会是
item.Book.Id ,将和 CartController 中 RemoveFromCart(int id, string
return) 的参数不合作。

 

  显示的法力如下:

图片 6

  

  2.增多摘要:大家在购物车存放了重重事物,通过摘要,能够展现购物资总公司额的缩略图,大家选取的岗位在顶部右上角的二个比较精晓的职位实行展现它,当然,还索要有点击的跳转按键方便呈现全数的购物清单页面。

  继续在 CartController 下增加产量二个 Action,名称叫Summary,再次来到值是1个总部视图:

        /// <summary>
        /// 摘要
        /// </summary>
        /// <returns></returns>
        public PartialViewResult Summary()
        {
            return PartialView(GetCart());
        }

  

  对应的 Summary.cshtml 

@model Wen.BooksStore.Domain.Entities.Cart

<div class="bookSummary">
    你的购物车:@Model.ComputeTotalValue() 
    @Html.ActionLink("结算", "Checkout", "Cart", new { retunUrl = Request.Url.PathAndQuery }, null)
</div>

 

  对应的布局页 _Layout.cshtml 修改的地方为:

图片 7

图片 8图片 9

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/Contents/Site.css" rel="stylesheet" />
</head>
<body>
    <div id="header">
        @{ Html.RenderAction("Summary", "Cart");}
        <div class="title">图书商城</div>
    </div>
    <div id="sideBar">
        @{ Html.RenderAction("Sidebar", "Nav"); }
    </div>
    <div id="content">
        @RenderBody()
    </div>
</body>
</html>

_Layout.cshtml

 

  增多了新的东西,css 也要开始展览修改:

图片 10图片 11

body {
}

#header, #content, #sideBar {
    display: block;
}

#header {
    background-color: green;
    border-bottom: 2px solid #111;
    color: White;
}

#header, .title {
    font-size: 1.5em;
    padding: .5em;
}

#sideBar {
    float: left;
    width: 8em;
    padding: .3em;
}

#content {
    border-left: 2px solid gray;
    margin-left: 10em;
    padding: 1em;
}

.pager {
    text-align: right;
    padding: .5em 0 0 0;
    margin-top: 1em;
}

    .pager A {
        font-size: 1.1em;
        color: #666;
        padding: 0 .4em 0 .4em;
    }

        .pager A:hover {
            background-color: Silver;
        }

        .pager A.selected {
            background-color: #353535;
            color: White;
        }

.item input {
    float: right;
    color: White;
    background-color: green;
}

.table {
    width: 100%;
    padding: 0;
    margin: 0;
}

    .table th {
        font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
        color: #4f6b72;
        border-right: 1px solid #C1DAD7;
        border-bottom: 1px solid #C1DAD7;
        border-top: 1px solid #C1DAD7;
        letter-spacing: 2px;
        text-transform: uppercase;
        text-align: left;
        padding: 6px 6px 6px 12px;
        background: #CAE8EA no-repeat;
    }

    .table td {
        border-right: 1px solid #C1DAD7;
        border-bottom: 1px solid #C1DAD7;
        background: #fff;
        font-size: 14px;
        padding: 6px 6px 6px 12px;
        color: #4f6b72;
    }

        .table td.alt {
            background: #F5FAFA;
            color: #797268;
        }

    .table th.spec, td.spec {
        border-left: 1px solid #C1DAD7;
    }

.bookSummary {
    width: 15%;
    float: right;
    margin-top: 1.5%;
}

Site.css

图片 12

 

大学就不均等了,宿舍相当于一个“家”,你的绝大好些个生存读书都在宿舍实行,它在您的生存中相对并吞着着贰个相对来讲首要性的地点,或好或坏。

贰、订单买下账单

  购物停止就是付账页面了,那里的订单付钱并不关乎支付接口的调用,只是利用邮件的款式开始展览通报而已。

  这里,笔者安插买单的时候需求须求用户输入一些音讯,如姓名、地址和信箱等音讯,在点击分明期小编再将那几个输入的信息与购物清单的新闻从系统的邮箱发到你所输入的信箱其中。一个相比较直观的图:

图片 13

  

  壹.在 Entities 中加多三个域模子 Contact.cs 表示维系人的消息。

图片 14

 

    /// <summary>
    /// 联系信息
    /// </summary>
    public class Contact
    {
        [Required(ErrorMessage = "姓名不能为空")]
        public string Name { get; set; }

        [Required(ErrorMessage = "地址不能为空")]
        public string Address { get; set; }

        [Required(ErrorMessage = "邮箱不能为空")]
        [RegularExpression(@"(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*\w\w)", ErrorMessage = "输入的邮箱地址不合法")]
        public string Email { get; set; }
    }

 

  CartController.cs 增多二个用以付账的 Action:

        /// <summary>
        /// 结算
        /// </summary>
        /// <returns></returns>
        public ViewResult Checkout()
        {
            return View(new Contact());
        }

 

  Checkout.cshtml 中的:

@model Wen.BooksStore.Domain.Entities.Contact

<div>
    @using (Html.BeginForm())
    {
        <div class="error">@Html.ValidationSummary()</div>
        <div>姓名: @Html.TextBoxFor(x => x.Name)</div>
        <div>地址: @Html.TextBoxFor(x => x.Address)</div>
        <div>邮箱: @Html.TextBoxFor(x => x.Email)</div>
        <div><input type="submit" value="提交" /></div>
    }

</div>

 

  这里运用的是模型校验,_Layout.cshtml 布局页须求引进 js:

    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

图片 15图片 16

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/Contents/Site.css" rel="stylesheet" />
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
</head>
<body>
    <div id="header">
        @{ Html.RenderAction("Summary", "Cart");}
        <div class="title">图书商城</div>
    </div>
    <div id="sideBar">
        @{ Html.RenderAction("Sidebar", "Nav"); }
    </div>
    <div id="content">
        @RenderBody()
    </div>
</body>
</html>

_Layout.cshtml

 

  尝试运转,会冒出以下页面,假诺消息不填的话会并发相关的谬误提醒:

图片 17

 

  二.接下来,要进入“提交”后的流水线了。

  今后还亟需三个零件用于拍卖订单,创造叁个用于订单管理的接口,和贰个该接口的兑现,再通过
Ninject 实行双边的绑定:

图片 18

    /// <summary>
    /// 订单处理
    /// </summary>
    public interface IOrderProcessor
    {
        /// <summary>
        /// 处理订单
        /// </summary>
        /// <param name="cart"></param>
        /// <param name="contact"></param>
        void ProcessOrder(Cart cart, Contact contact);
    }

 

  建立三个贯彻该接口用于拍卖订单的实体类,这里并不是调用支付接口,而是轻松通过
BCL 中的进行邮件的发送。

图片 19

   

  EmailOrderProcessor.cs:

    /// <summary>
    /// 邮件订单处理器
    /// </summary>
    public class EmailOrderProcessor : IOrderProcessor
    {
        /// <summary>
        /// 发送人
        /// </summary>
        public static class Sender
        {
            /// <summary>
            /// 账号
            /// </summary>
            public static string Account = "你的@qq.com";

            /// <summary>
            /// 密码
            /// </summary>
            public static string Password = "xxx";
        }

        /// <summary>
        /// 处理订单
        /// </summary>
        /// <param name="cart"></param>
        /// <param name="contact"></param>
        public void ProcessOrder(Cart cart, Contact contact)
        {
            if (string.IsNullOrEmpty(contact.Email))
            {
                throw new Exception("Email 不能为空!");
            }

            var sb = new StringBuilder();
            foreach (var item in cart.GetCartItems)
            {
                sb.AppendLine($"《{item.Book.Name}》:{item.Book.Price} * {item.Quantity} = {item.Book.Price * item.Quantity}");
            }

            sb.AppendLine($"总额:{cart.GetCartItems.Sum(x => x.Quantity * x.Book.Price)}");
            sb.AppendLine();
            sb.AppendLine($"联系人:{contact.Name} {contact.Address}");

            //设置发件人,发件人需要与设置的邮件发送服务器的邮箱一致
            var fromAddr = new MailAddress(Sender.Account);
            var message = new MailMessage { From = fromAddr };

            //设置收件人,可添加多个,添加方法与下面的一样
            message.To.Add(contact.Email);
            //设置抄送人
            message.CC.Add(Sender.Account);
            //设置邮件标题
            message.Subject = "您的订单正在出库...";
            //设置邮件内容
            message.Body = sb.ToString();
            //设置邮件发送服务器,服务器根据你使用的邮箱而不同,可以到相应的 邮箱管理后台查看,下面是QQ的

            var client = new SmtpClient("smtp.qq.com", 25)
            {
                Credentials = new NetworkCredential(Sender.Account, Sender.Password),
                EnableSsl = true
            };

            //设置发送人的邮箱账号和密码
            //启用ssl,也就是安全发送
            //发送邮件
            client.Send(message);
        }

 

  CartController 也急需稍作调治:

图片 20

 

  还要在 CartController 中额外增多二个带 [HttPost] 特性的名称叫Checkout 方法:

图片 21

 

        /// <summary>
        /// 结算
        /// </summary>
        /// <param name="contact"></param>
        /// <returns></returns>
        [HttpPost]
        public ViewResult Checkout(Contact contact)
        {
            if (!ModelState.IsValid)
                return View(contact);

            var cart = GetCart();
            _orderProcessor.ProcessOrder(cart, contact);
            cart.Clear();
            return View("Thanks");
        }

 

  当校验成功时,会调用接口发一条音信,并且清空已部分购物车,然后跳转到钦定的三个新视图页:

图片 22

  

  新建 Thanks.cshtml,内容如下:

Thanks

 

  别忘了加多绑定哦,使用 DI 容器将两者举办绑定:

图片 23

 

  运维页面,试试效果呢:

图片 24

   看来,好像成功了哦:

图片 25

 

 

 


【博主】反骨仔

【出处】http://www.cnblogs.com/liqingwen/p/6652564.html 

【参考】《精通 ASP.NET MVC …》

不精晓有个别许人和本身一样曾经感觉宿舍像三个鬼世界般折磨人的地方,壹想到回宿舍心里就发毛,尽大概地在自习室体育场合多待也不愿回到宿舍?

简介

  上一节大家成功了七个至关重要作用:增多到购物车和分类导航,那一节大家会做到全套购物车的流水生产线,以及订单管理。

  该类别首要作用与知识点如下:

    分类、产品浏览、购物车、买单、CRUD(增删改查)
管理、发邮件、分页、模型绑定、认证过滤器和单元测试等(估量剩余两篇,星期五(因为周四不上班)先公布1篇)。

     【备注】项目利用 VS二〇一四 + C#6举行开拓,有标题请发布在留言区啊,还有,页面长得极不美观,请见谅。

 

但某个舍友就通晓相互帮助温暖人心,她会在本人回宿舍的那一刻说一句“大暑你回去了哟”,会在她出来打热水时无条件问小编一句“小暑要不要自身帮您打热水啊?”会在某说话抱着笔者说“有大暑在小编身边真好”。这样的她温柔迷人,善良珍惜,在自家上床的时候他会帮作者和舍友说“立春在睡眠,我们讲话声音小部分啊!”其实非凡时候的本人正被舍友吵得闷在被子里有个别埋怨地强求自身入睡,听到他为笔者说话,心里确实一级感动。

  《[一步步塑造一个轻便易行的 MVC 电商网址

BooksStore(一)](http://www.cnblogs.com/liqingwen/p/6640861.html)》(发布时间:2017-03-30 )

      《一步步构建多少个简短的 MVC
电商网址 –
BooksStore(2)
》(发布时间:2017-0三-31)

自家不抵抗在外部,并不表示不在沉Murray爆发,有个别事忍久了就欠有意思了。

目录

  • 做到购物车
  • 订单付账

 


一步步创设二个粗略的 MVC 电商网址 – BooksStore(3)

  本体系的
GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore

只想说一言难尽…

譬如说,你要去打水喝,她说不行什么人你能够帮我带一瓶吗?你硬着头皮答应担忧中是拒绝的,她顺手把双陆瓶给您说了句多谢,你就去了,可用的是你的水卡。

一、

本身在睡眠你在吵,你一睡觉就让小编闭嘴,那种人也顶尖招人讨厌。

怎么样的场馆最令人生气呢?便是自家提示了你你还不改,那就TMD太不强调解的人了。你认为宿舍是你家啊!而且对于这么的舍友结业将来绝对断绝来往,何人嘛。

都说大学宿舍关系错综复杂,作者上了大学渐渐知道了。不是您学乖单纯朴善良良就足以的,那样的你会被指使做一些不愿干又不好拒绝的事。

拿自家以往的宿舍说吧,大家宿舍有三个人属于“话唠”型,笔者和另2个湖南的孙女属于“闷骚”型。最近大家就因为宿舍太吵闹得很不乐意。笔者这多个“话唠”型舍友只要聚到一同,就好像总有话题聊,各自就某一事件见报本人的见识,然后有同意的就激动地附和,满面春风地质大学叫大笑。这个小编非常小管,她们心旷神怡就好。只是梦想注意一下光阴,举例清晨到了要午间休息的时候,早上到了要熄灯的时候,就不要再叨叨了,声音正好地放低也是能够的。

图片 26

那二种说不出来好坏,各有各的特征啊。例如说,合适的“话唠”能够活跃宿舍氛围,令宿舍充满欢声笑语,但纵然过度就欠有意思了。

对不起,小编可不是圣母玛拉斯维加斯,不精晓无条件付出。

从小学五年级开头自己就留宿,加上6年级、初级中学三年、高级中学两年,已经有柒年了,但是集体住宿生活依旧不太符合本身,比不上单身1个人住来得高兴。究其原因,大概是自家从小1位住惯了,因为爸妈常年不在家的案由,作者和曾祖父奶奶一齐生活,从5年级起头本人就一个人睡四个房间,习贯了安安静静,自身做本身的事。

图片 27

原因唯有一个——宿舍太吵。看似简单的原委背后,却能深挖出大多因果。

图片 28

自己在宿舍属于那种话少安静的品类,总是默默做着和睦的事。我们宿舍是6俗尘,上床下桌。笔者深信不疑每种宿舍总有一部分“话唠”型和“闷骚”型舍友,“话唠”型属于话特别多,特八卦的,一点琐事都能拿出去叨叨个半天。“闷骚”型属于话很少,沉浸在友好的社会风气里,就算心里某个波澜起伏也不会在宿舍公然叫嚣。

二、

诸如,你从热水房打了1瓶开水,筹算分今明两Smart用,她一句诶那些什么人笔者不想去打热水,你有吧能够借我好几啊?你硬着头皮答应了心神是不容的。何人让你人善良呢?因为嘴笨说不出拒绝的话,又怕伤了和舍友的情义,所以您挑选逃避本身的心灵,做出不得已的决定。那样的你感到很压抑,扪心自问凭什么自个儿将要给他做那做那,她为本人做了吗呀。

归根到底,人心是肉长的,你对本人好、尊重自己,作者也看在眼里、记在心尖。

自己只想说:宿舍不是家、舍友不是朋友。

葬心YX,大第22中学国语言法学系,喜欢记录生活,抒发真实际情况感,小编的文字中有未有哪一句打动到你呢?

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图