http://blog.sina.com.cn/s/blog_6ad539a90100rag1.html
在本节中,我们将要创建一个下订单控制器,该控制器将获取购买者的收货地址与付款信息。在下订单之前,用户首先需要在网站中进行注册,因此在访问这个控制器的时候需要进行用户身份认证处理。

点击图9-1中所示视图中的“结算”链接之后,用户将进入下订单处理过程。

图9-1 点击“结算”链接

如果用户尚未登陆,他们将会看见登陆视图,如图9-2所示。

图9-2 登陆视图

用户成功登陆之后,将看见收货信息填写视图,如图9-3所示。

图9-3 收货信息填写视图

填写完毕收货信息并提交之后,他们将会看见订单完成通知视图,如图9-4所示。

图9-4 订单完成通知视图

企图查看一个不存在的订单或者非注册用户的订单信息时,他们会看见如图9-5中所示的错误视图。

图9-5 错误视图

9.2 转入购物车中的信息

当匿名用户点击“结算”链接的时候,他们将会提示需要注册并登陆。用户当然希望登陆后能够继续使用在登陆之前他们放入购物车中的信息,所以我们需要在用户注册并且登陆之后取得他们在注册或登陆之前放入购物车中的信息。

这个处理是非常简单的,因为我们的ShoppingCart类中已经有了一个方法来将该用户登陆后的用户名与登陆前的购物车中的信息合并起来,我们只需要在用户注册及登陆后直接调用这个方法就可以了。

打开之前我们在处理用户身份认证时追加的AccountController类,假如如下所示的MigrateShoppingCart方法。

private void MigrateShoppingCart(string UserName)

{

// 获取登陆用户购物车中的信息

var cart = ShoppingCart.GetCart(this.HttpContext);

cart.MigrateCart(UserName);

Session[ShoppingCart.CartSessionKey] = UserName;

}

接下来,修改在HttpPost请求时调用的LogOn方法,当用户登陆成功后调用MigrateShoppingCart,代码如下所示。

[HttpPost]

public ActionResult LogOn(LogOnModel model, string returnUrl)

{

if (ModelState.IsValid)

{

if (MembershipService.ValidateUser(model.UserName, model.Password))

{

MigrateShoppingCart(model.UserName);

FormsService.SignIn(model.UserName, model.RememberMe);

if (Url.IsLocalUrl(returnUrl))

{

return Redirect(returnUrl);

}

else

{

return RedirectToAction("Index", "Home");

}

}

else

{

ModelState.AddModelError("", "用户名或密码输入不正确");

}

}

// 登陆失败,重新显示登陆画面

return View(model);

}

在Register这个HttpPost请求时调用的action方法中做出同样的修改,当用户注册成功时立即读取用户购物车中的信息。

[HttpPost]

public ActionResult Register(RegisterModel model)

{

if (ModelState.IsValid)

{

// 尝试用户注册

MembershipCreateStatus createStatus =

MembershipService.CreateUser(model.UserName,

model.Password, model.Email);

if (createStatus == MembershipCreateStatus.Success)

{

MigrateShoppingCart(model.UserName);

FormsService.SignIn(model.UserName, false);

return RedirectToAction("Index", "Home");

}

else

{

ModelState.AddModelError("",

AccountValidation.ErrorCodeToString(createStatus));

}

}

// 注册失败,重新显示登陆视图

ViewBag.PasswordLength = MembershipService.MinPasswordLength;

return View(model);

}

这样就可以了。现在一个用户成功登陆或注册后,该用户仍然能够继续使用他在购物车中的信息。

9.3 创建下订单控制器

鼠标右击Controllers文件夹,追加一个新的名为CheckoutController的控制器。保持“为‘创建’、‘更新’、‘删除’和‘详细信息’方案添加操作方法”复选框为非选取状态,如图9-6所示。

图9-6 添加下订单控制器

首先,为该控制器添加Authorize属性,表示用户在下订单之前首先需要注册及登陆,代码如下所示。

namespace MvcBookStore.Controllers

{

[Authorize]

public class CheckoutController : Controller

请注意:这里添加Authorize属性的方法与为StoreManager控制器添加Authorize属性的方法非常类似,但是在 StoreManager控制器中要求登陆用户的身份必须为管理员,而在CheckoutController控制器中只要求用户登陆,但并不要求用户必 须为管理员。

为了简单起见,本教程中不处理用户的收货信息。

与StoreController控制器中相同,我们需要添加引用BookStoreEntities类的一个实例,对象名为storeDB。为了能够使 用BookStoreEntities类,我们还需添加引用MvcBookStore.Models命名空间。代码如下所示。

using System;

using System.Linq;

using System.Web.Mvc;

using MvcBookStore.Models;

namespace MvcBookStore.Controllers

{

[Authorize]

public class CheckoutController : Controller

{

BookStoreEntities storeDB = new BookStoreEntities();

在CheckoutController控制器中添加如下几个方法:

AddressAndPayment(在GET请求时调用):显示一个表单,允许用户输入收货信息。

AddressAndPayment(在POST请求时调用):验证用户输入的收货信息,处理订单。

Complete:用户下订单成功后显示一个操作完成确认视图。该视图中包括用户的订单号,用以通知用户订单已成功创建。

首先,让我们将Index方法(创建控制器时被自动创建)重命名为AddressAndPayment方法(填写收货信息)。该方法只被用来显示收货信息填写视图,所以不需要任何模型信息,代码如下所示。

//

// GET: /Checkout/AddressAndPayment

public ActionResult AddressAndPayment()

{

return View();

}

在POST请求时调用的AddressAndPayment方法中的处理与StoreManager控制器中的处理非常类似:尝试接收表单信息,并且创建订单。如果失败,则重新显示表单(收货信息填写表单。

在对表单信息验证通过之后,我们将信息保存在订单中,通知ShoppingCart对象来完成订单处理,并且重定向到Complete方法,代码如下所示。

//

// POST: /Checkout/AddressAndPayment

[HttpPost]

public ActionResult AddressAndPayment(FormCollection values)

{

var order = new Order();

TryUpdateModel(order);

try

{

order.Username = User.Identity.Name;

order.OrderDate = DateTime.Now;

//保存订单

storeDB.Orders.Add(order);

storeDB.SaveChanges();

//处理订单信息

var cart = ShoppingCart.GetCart(this.HttpContext);

cart.CreateOrder(order);

return RedirectToAction("Complete",new { id = order.OrderId });

}

catch

{

//无效,重新返回显示错误信息

return View(order);

}

}

订单处理成功之后,用户将被重定向到Complete方法。该方法为订单完成通知信息而显示订单号实现一个简单检查,检查该订单是否属于当前登陆用户。代码如下所示。

//

// GET: /Checkout/Complete

public ActionResult Complete(int id)

{

// 验证当前用户是否拥有这张订单

bool isValid = storeDB.Orders.Any(o => o.OrderId == id

&&o.Username == User.Identity.Name);

if (isValid)

{

return View(id);

}

else

{

return View("Error");

}

}

请注意:错误视图将被自动创建在Views文件夹下的Shared文件夹中。

完整的CheckoutController控制器中的代码如代码清单9-1所示。

代码清单9-1 完整的CheckoutController控制器中的代码

using System;

using System.Linq;

using System.Web.Mvc;

using MvcBookStore.Models;

namespace MvcBookStore.Controllers

{

[Authorize]

public class CheckoutController : Controller

{

BookStoreEntities storeDB = new BookStoreEntities();

//

// GET: /Checkout/AddressAndPayment

public ActionResult AddressAndPayment()

{

return View();

}

//

// POST: /Checkout/AddressAndPayment

[HttpPost]

public ActionResult AddressAndPayment(FormCollection

values)

{

var order = new Order();

TryUpdateModel(order);

try

{

order.Username = User.Identity.Name;

order.OrderDate = DateTime.Now;

//保存订单

storeDB.Orders.Add(order);

storeDB.SaveChanges();

//处理订单

var cart =

ShoppingCart.GetCart(this.HttpContext);

cart.CreateOrder(order);

return RedirectToAction("Complete",new { id =

order.OrderId });

}

catch

{

//无效,重新返回显示错误信息

return View(order);

}

}

//

// GET: /Checkout/Complete

public ActionResult Complete(int id)

{

//  验证当前用户是否拥有这张订单

bool isValid = storeDB.Orders.Any(o => o.OrderId ==

id &&o.Username == User.Identity.Name);

if (isValid)

{

return View(id);

}

else

{

return View("Error");

}

}

}

}

9.4 添加收货信息填写视图

现在,让我们来添加收货信息填写视图。在任意一个AddressAndPayment方法中点击鼠标右键,使用Order(订单)类创建一个强类型视图,使用Edit(编辑)模板,如图9-7所示。

图9-7 添加收货信息填写视图

这个视图将要使用两个我们之前在StoreManager控制器的书籍编辑视图中使用过的两个技巧。

  • 我们将使用Html.EditorForModel()帮助器方法来为Order(订单)模型类显示各属性编辑控件。
  • 我们将对Order类使用验证属性来强制使用验证规则。

修改表单中的代码,使用Html.EditorForModel()帮助器方法。完整的添加收货信息填写视图中的代码如代码清单9-2所示。

代码清单9-2 完整的添加收货信息填写视图中的代码

@model MvcBookStore.Models.Order

@{

ViewBag.Title = "填写收货信息";

}

<script

src="@Url.Content("~/Scripts/jquery.validate.min.js")"

type="text/javascript"></script>

<script

src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.

min.js")"

type="text/javascript"></script>

@using (Html.BeginForm()) {

<h2>填写收货信息</h2>

<fieldset>

<legend>收货信息</legend>

@Html.EditorForModel()

</fieldset>

<input type="submit" value="提交订单" />

}

转载于:https://www.cnblogs.com/quietwalk/archive/2011/07/05/2098177.html

ASP.NET MVC3书店--第九节 注册与下订单(第一部分)(转)相关推荐

  1. ASP.NET MVC3书店--第二节 控制器(转)

    http://blog.sina.com.cn/s/blog_6ad539a90100qe6x.html 在传统的Web应用程序中,输入的URL通常被映射为一个磁盘文件.例如:一个类似"/P ...

  2. ASP.NET MVC3书店--第七节 用户及身份验证(转)

    http://blog.sina.com.cn/s/blog_6ad539a90100r7jx.html 现在的问题是任何用户都可以通过StoreManager控制器来访问我们的书籍管理页面.接下来让 ...

  3. ASP.NET MVC3书店--第五节 表单编辑(第二部分)(转)

    http://blog.sina.com.cn/s/blog_6ad539a90100r469.html 5.5 使用HTML帮助器来截短文字 使用我们的StoreManager控制器中的Index方 ...

  4. ASP.NET MVC3 快速入门--第二节 添加一个控制器

    MVC的全称为model-view-controller(模型-视图-控制器).MVC是一种开发应用程序的模式,这个模式已经具有了很好的框架架构,并且十分容易维护.使用MVC开发出来的应用程序一般包括 ...

  5. ASP.NET MVC3 快速入门-第四节 添加一个模型(转)

    在本节中我们将追加一些类来管理数据库中的电影.这些类将成为我们的MVC应用程序中的"模型"部分. 我们将使用一个.NET Framework的被称之为"Entity Fr ...

  6. [译]Professional ASP.NET MVC3(01)-Chapter 1:Getting Started(上)

    本章概要 理解ASP.NET MVC ASP.NET MVC3 预览 如何创建MVC3应用程序 MVC应用程序结构 本章首先简要介绍ASP.NET MVC, 解释它怎样适应ASP.NET MVC的历史 ...

  7. Asp.Net Mvc3.0(MEF依赖注入实例)

    前言 在http://www.cnblogs.com/aehyok/p/3386650.html前面一节主要是对MEF进行简单的介绍.本节主要来介绍如何在Asp.Net Mvc3.0中使用MEF. 准 ...

  8. ASP.NET MVC3 快速入门

    第一节 概述    (2011-02-23 20:57:18)  转载 标签: web应用程序 分类: ASP.NETMVC3 1.1  本教程的学习内容     在本教程中,你将学会如下内容: •  ...

  9. asp.net mvc3.0安装失败之终极解决方案

    安装失败截图 原因分析 因为vs10先安装了sp1补丁,然后安装的mvc3.0,某些文件被sp1补丁更改,导致"VS10-KB2483190-x86.exe"安装不了,造成安装失败 ...

最新文章

  1. log4j2的xml的配置样例
  2. Redis Sentinel机制与用法
  3. ecs服务器配置git_阿里云 ECS服务器(CentOS 7)安装和使用Gitlab教程
  4. mybatis select语句会默认带排序吗_MyBatis中#和$的区别详解
  5. [原创]性能测试之“Windows性能监视器”
  6. Ajax 技术资源中心
  7. 简单数独的DFS求解
  8. 5mm方格本打印模板_自制方格本模板
  9. android 经纬度方向,Android获取经纬度计算距离介绍
  10. Docker创建镜像Nuget失败
  11. W3C CSS验证方法
  12. 爬虫时候遇到python connection error max retries exceeded whith url 怎么解决?
  13. java求圆和梯形_jsp与javabean例子 求三角形、圆、梯形面积
  14. 跟小博老师一起学习数据库 ——MySql安装
  15. 【C语言】复数的四则运算与复数运算的头文件
  16. grep中的正则表达式
  17. 国信证券学习系列(4)
  18. Java中的this关键字(三种用法)
  19. 第3周练习 恺撒密码
  20. excel高级筛选_Excel自动筛选还是高级筛选?

热门文章

  1. 快速提升网站收录量的技巧有哪些?
  2. svn 不支持http 客户端_Xversion for mac(SVN客户端)
  3. Dropout, DropConnect ——一个对输出,一个对输入
  4. 基尼指数——基尼系数是指国际上通用的、用以衡量一个国家或地区居民收入差距的常用指标。基尼系数介于0-1之间,基尼系数越大,表示不平等程度越高。...
  5. 联机事务处理OLTP(on-line transaction processing)和联机分析处理OLAP(On-Line Analytical Processing)...
  6. 微信小程序input批量赋值(setData)
  7. Jquery源码解析-设计理念
  8. SQL Server2008(一)简介
  9. 2019~2020这个时间段适合买房吗?
  10. [工具]Tomcat CVE-2017-12615 远程代码执行