zoukankan      html  css  js  c++  java
  • MVC-07 案例2

    二、电子商务网站

        掌握该网站的开发流程和设计思路,并为数据模型中商品、商品分类,这两个类编写代码。

    1.需求分析

    2.数据模型规划

    (1)商品类别

    (2)商品信息

    (3)会员信息

    (4)购物车项目

    (5)订单主文件

    (6)订单明细

    3.控制器架构规划

    (1)商品浏览

    (2)会员功能

    (3)购物车功能

    (4)订单结账功能

    4.创建视图页面

    (1)商品浏览

    a.首页/商品分类

    b.商品列表

    c.商品明细

    (2)会员功能

    a.会员注册

    b.会员登录

    c.购物车功能

    d.订单结账功能

    e.编写母版页面

    5.添加数据库与购物车功能

    (1)添加信息内容类

    (2)添加导览属性

    (3)启用自动数据库迁移

    (4)商品浏览

    (5)会员功能

    (6)购物车功能

    (7)订单结账功能

    6.强化会员功能

    (1)修正会员注册机制

    (2)完成会员E-mail验证功能

    (3)修正会员登录机制

    (4)检查会员注册的账户是否重复

        会员注册的时候,不允许会员注册重复的账户名称,已在MemberController的Register动作中已经实现,在点击注册按钮后,提交处理。

        ASP.Net MVC提供了一种远程验证的机制,可以让网页在不换页的情况下就能取得验证结果,这部分同样是通过jQuery Validate套件帮助我们完成,通过ASP.NET MVC的帮助,我们甚至可以完全不碰触View视图页面,就能满足这个需求。

        要使用ASP.Net MVC的远程验证功能,有两个地方必须设置,一个是在Member数据模型类别的Email属性上新增一个Remote属性(Attribute),这个属性必须传入要运行远程验证的Controller与Action名称,在这个例子中,我们的Action名称用CheckDup,而Controller设置为Member,远程验证时要用的HTTP方法(HttpMethod)为POST方法。这部分更改后代码段如下:

      [DisplayName("会员账号")]

            [Required(ErrorMessage = "请输入Email地址")]

            [Description("我们直接以Email当成会员的登录账号")]

            [MaxLength(250, ErrorMessage = "Email地址长度无法超过250个字符")]

            [DataType(DataType.EmailAddress)]

            [Remote("CheckDup", "Member", HttpMethod = "POST", ErrorMessage = "您输入的Email已经有人注册过了!")]

            public string Email { get; set; }

    另一个就是在MemberController里新增一个CheckDup动作,接收客户段发过来的验证要求。这部分的程序代码如下:

    [HttpPost]

            public ActionResult CheckDup(string Email)

            {

                var member = db.Members.Where(p => p.Email == Email).FirstOrDefault();

                if (member != null)

                    return Json(false);

                else

                    return Json(true);

            }

    在撰写提供远程验证的Action时,有四个注意事项。

    (1)传入的参数名称必须等同于要验证的那个属性名称。例如,我们要验证Email属性是否重复,那么我们的CheckDup激活的第一个参数就必须使用Email作为变量名称,这样才能通过模型绑定取得信息。

    (2)结果必须使用JsonResult回传,使用System.Web.Mvc.Controller基类中的Json辅助方法帮助我们输出这个结果。

    (3)回传的信息,只要响应结果是true,就代表验证成功(代表账号没有重复),如果回传false就会被视为验证失败,并显示默认的错误消息。除此之外,只要任何不是true或false的属性,都会被视为验证失败时的自定义错误消息,如下程序演示:

    return Json(“您输入的Email已经有人注册过了!”);

    (4)如果你使用HTTP GET方法进行验证,那么Json辅助方法必须输入第二个参数,明确指定允许Get方法调用这个动作,如下程序演示:

    return Json(false,JsonRequestBehavior.AllowGet);

    设置好之后就能够测试远程验证是否成功,我们也可以开启IE开发者工具分析远程验证的过程,浏览器确实会发出一个Ajax要求到/Member/CheckDup,并取得一个验证结果,如下图所示。

    7.强化现有的ASP.NET MVC程序

    (1)抽离多个Controller重复的程序代码

    到当前应该可以发现,在不同的Controller里出现了不少重复的程序代码,每一个Controller里都有db字段,在OrderController与MemberController里都有Carts属性(Property)。我们可以将这些程序代码统一并集中到一个自定义的基类中。

    在Controllers目录下新增一个BaseController.cs类别,并将db和Carts属性移动过来。请注意这两个类别层级的字段与属性移过来之后,要声明成public或protected才能让继承的子类访问。最后完成的BaseController程序代码如下。

    public class BaseController : Controller

        {

            protected ShoppingContext db = new ShoppingContext();

            protected List<Cart> Carts

            {

                get

                {

                    if (Session["Carts"] == null)

                    {

                        Session["Carts"] = new List<Cart>();

                    }

                    return (Session["Carts"] as List<Cart>);

                }

                set { Session["Carts"] = value; }

            }

        }

    接着我们把每一个Controller类别里的父类声明改成BaseController,程序如下所示:

    public class HomeController : BaseController

    当然也要记得移除每一个Controller类里的db与Carts。

    (2)将调试用的程序代码区分不同配置

    每一个通过VS创建的项目默认都会区分Debug与Release配置,利用这个配置可以帮助我们编译不同环境使用不同程序,切换方案配置的界面如下图所示。

                           

    我们在HomeController里曾经有几个Action添加过几段创建默认信息的程序代码,这时我们就可以利用#if与#endif指示词设置特定程序代码段是否要出现在特定方案配置下,如下程序演示:

    #ifDEBUG的意思是,当前项目选择DEBUG配置时,这段程序代码才会被编译进.NET组件(DLL)里。当选择Release配置时,程序代码全都变成了灰色,也代表着在Release配置下编译改程序代码不会被编译进.NET组件。

    (3)替产品列表加上分页功能

        当商品信息越来越多,分页是必要的功能,可以采用PagedList函数库,通过NuGet程序包管理来安装,选择PagedList.Mvc,界面如下图。

        关于PagedList函数库,可以参考以下网址:https://github.com/TroyGoode/PagedList

        分页功能,主要开发工作为以下三个部分:

    • 取得IEnumerable或IQueryable类型的源数据,或继承这两个类型的子类型也可以。

    --在HomeController的ProductList中,取得分页组件的源数据,代码如下。

    var data = db.ProductCategories.ToList();
    • 通过ToPagedList扩充方法,取得分页后的结果信息,并将信息传入View里。

    --在HomeController中,添加命名空间引用。

    using PagedList;

    --我们原本是传入data到View里,但现在要通过ToPagedList扩展方法取得分页信息。使用ToPagedList扩展方法时,pageNumber参数是页码,其值从1开始算起,pageSize参数是每页取得的信息条数,更改后的代码段如下。

    var pagedData = data.ToPagedList(pageNumber: 1, pageSize: 10);
    return View(pagedData);

    --通过ToPagedList扩充方法取得的信息类型为IPagedList<T>,这个类型继承自IEnumerable<T>,所以原本做好的强类型视图也面并不会有任何影响。程序运行后,页面最多显示10条信息,因为已经被ToPagedList扩展方法限定了输出量。

    • 在View页面中通过@Html.PagedListPager辅助方法输出分页所需的分页导览链接。

    --在HomeProductList视图中添加命名空间引用。

    @using PagedList
    @using PagedList.Mvc

        在PagedList.Mvc分页套件里内建了一个CSS样式表单,位于项目的Content目录下,文档名为PagedList.css,该套件提供了一个默认的分页所需的样式。在使用@Html.PagedListPager扩充方法之前必须先装入这个样式表单文档,才能看到比较漂亮的分页版面。可以直接在页面中装入,也可以在主版页面中装入,语法如下。

    <link href="~/Content/PagedList.css" rel="stylesheet" />

        @Html.PagedListPager扩充方法总共有三个参数可以传入,第一个是list参数,要传入类型为IPagedList<T>的信息;第二个是generatePageUrl参数,负责传入一个Func<int, string>类型,传入的int参数是生成分页链接的页码编号,回传的string类型则是一个超链接的URL地址;第三个options参数则是用来微调分页输出的用途,需传入一个PagedListRenderOptions类型的物件。

        在我们的例子里,只要输入list与generatePageUrl即可,data需要转换为IPagedList<T>类型,Url.Action辅助方法帮助我们生成分页的链接,传入Url.Action辅助方法的Action名称必须和现有页面的Action名称一样,而最后传入的路由参数p则是要传入的页码。完成后的代码如下。

    @{
        var data = Model as IPagedList<Shopping1031.Models.Product>;
    }
    @Html.PagedListPager(list:data,generatePageUrl:page=>Url.Action("ProductList",new {p=page}))

        设置完成后的运行界面如下图。

                           

        这时你会发现,不管怎样换页都只会停在第一页,那是因为我们的Controller还没有针对传入的p查询字符串做出反应,所以我们还需要微调一下ProductList动作方法,新增一个传入的p参数,并且给予一个默认值1,代表当没有传入p参数时默认就是现实第一页。完成的代码如下。

        public ActionResult ProductList(int id,int p=1)
        {
            …
            var pagedData = data.ToPagedList(pageNumber: p, pageSize: 10);
            return View(pagedData);
    … }

        完成后,完整的分页功能就已经设置完毕,如下图。

    请为电子商务网站设计类图,并为数据模型中基本订单信息和订单明细,这两个类编写代码。 

  • 相关阅读:
    智器SmartQ T7实体店试用体验
    BI笔记之SSAS库Process的几种方案
    PowerTip of the Day from powershell.com上周汇总(八)
    PowerTip of the Day2010071420100716 summary
    PowerTip of the Day from powershell.com上周汇总(十)
    PowerTip of the Day from powershell.com上周汇总(六)
    重新整理Cellset转Datatable
    自动加密web.config配置节批处理
    与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable
    在VS2003中以ClassLibrary工程的方式管理Web工程.
  • 原文地址:https://www.cnblogs.com/meetyy/p/3477593.html
Copyright © 2011-2022 走看看