二、电子商务网站

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

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: , pageSize: );
return View(pagedData);

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

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

--在Home\ProductList视图中添加命名空间引用。

@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=)
{

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

}

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

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

MVC-07 案例2的更多相关文章

  1. MVC 小案例 -- 信息管理

    前几次更新博客都是每次周日晚上到周一,这次是周一晚上开始写,肯定也是有原因的!那就是我的 Tomact 忽然报错,无法启动,错误信息如下!同时我的 win10 也崩了,重启之后连 WIFI 的标志也不 ...

  2. Java基础-SSM之Spring和Mybatis以及Spring MVC整合案例

    Java基础-SSM之Spring和Mybatis以及Spring MVC整合案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 能看到这篇文章的小伙伴,详细你已经有一定的Java ...

  3. Kubernetes中分布式存储Rook-Ceph的使用:一个ASP.NET Core MVC的案例

    在<Kubernetes中分布式存储Rook-Ceph部署快速演练>文章中,我快速介绍了Kubernetes中分布式存储Rook-Ceph的部署过程,这里介绍如何在部署于Kubernete ...

  4. spring3 jsp页面使用<form:form modelAttribute="xxxx" action="xxxx">报错,附连接数据库的spring MVC annotation 案例

    在写一个使用spring3 的form标签的例子时,一直报错,错误信息为:java.lang.IllegalStateException: Neither BindingResult nor plai ...

  5. Spring mvc简单案例

    jar包 <!--junit--><dependency> <groupId>junit</groupId> <artifactId>jun ...

  6. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 07. View的Model 和 Tag Helpers

    student添加一个属性BirthDate 然后把生成数据的地方,字段也加上 建立ViewModel list转换为ViewModel 进一步改进代码 StudentViewModel HomeIn ...

  7. MVC出错案例之一:主外键映射失败

    今天在编写DomainModel和DomainMapper,最后放到OnModelCreating中运行的时候,给我抛出了如下错误: One or more validation errors wer ...

  8. MVC登录案例

    1.在Controllers文件夹里面新建一个控制器HomeController;2.在默认的Index方法里面添加一个视图,名字跟Controller中的方法名一样叫Index,添加后的视图文件会在 ...

  9. 简单干净的C# MVC设计案例:BrothersDropdownList()

    团队切换器 在/Teams/Details?id=xxx的页面,有这样一个控件,使得不需要回到/Teams/Index就能轻松切换团队: 由于这种团队切换控件比比皆是,比如在团队故事板中(以及其他地方 ...

  10. asp.net mvc上传图片案例

    1.放在ajax.BeginForm里,不好使,同asp.net 表单中 fileupload控件不支持ajax差不多吧,如果异步的话可以借助jquery.form.js,很方便 2. //上传文件  ...

随机推荐

  1. JavaScript之call()和apply()方法详解

    简介:apply()和call()都是属于Function.prototype的一个方法属性,它是JavaScript引擎内在实现的方法,因为属于Function.prototype,所以每个Func ...

  2. Javascript 获取窗口的大小和位置

    在Javascript中可以使用OuterWidth,OuterHeight 获取浏览器的大小.用 innerWidth,innerHeight 来获取窗口的大小(除去浏览器边框部分).对于IE6 及 ...

  3. 优质UI的7条准则(一)

    本文原文来自于 Medium:https://medium.com/@erikdkennedy/7-rules-for-creating-gorgeous-ui-part-1-559d4e805cda ...

  4. ​c++ 调用DLL函数,出现错误

    ​c++ 调用DLL函数,出现错误 Run-Time Check Failure #0 - The value of ESP was not properly saved across a funct ...

  5. 一周学会Mootools 1.4中文教程:(6)动画

    先看一下动画的参数设置: 参数: fps - (number:默认是50) 每秒的帧数. unit - (string:默认是 false) 单位,可为 'px','em',或 '%'. link - ...

  6. Howie带你云上飘-新浪云

    介绍一下怎么在sae上做个网站 前言 曾经,sae是收费的,计时收费,还挺贵的呢.所以就试玩了一下,没敢继续鼓捣.后来,云计算越来越火了,新浪也不差钱嘛,于是直接给新注册的开发者送好多豆子,于是,免费 ...

  7. [Java]使用队列求解josephus问题

    约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环. 有个囚犯站成一个圆圈,准备处决.首先从一个人开始,越过个人(因为第一个人已 ...

  8. Windows Phone

    错误: DEP6100 : 引导阶段“正在连接到设备”出现以下意外错误: SmartDeviceException - Windows Phone IP over USB Transport (IpO ...

  9. Scale-up(纵向扩展) vs Scale-out(横向扩展)

    转载:http://wuaner.iteye.com/blog/1843799 http://www.javaworld.com/article/2077780/java-web-developmen ...

  10. Html 小插件5 百度搜索代码2

    网页添加百度搜索框代码大全 ★ 用法:在下面选择合适的样式,复制代码到网页中相应位置粘贴即可. ★ 样式一(200×30)代码: <iframe id="baiduframe" ...