《Pro ASP.NET MVC 3 Framework》学习笔记之十五【示例项目SportsStore】

简介:

绑定Shopping Cart

定义购物车Cart的实体,购物车是我们程序业务领域的一个部分,所以在我们领域模型(Domain Model)里面添加一个cart的实体是合理的。在SportsStore.Domain的Entities文件夹下添加一个Cart的实体类,如下所示:

View Code

添加几个测试方法测试下,如下所示:

View Code

编辑Views/Shared/ProductSummary.cshtml,如下所示:

View Code

当我们提交表单时,会调用CartController下的AddToCart action方法。

Note:我们通过Html.BeginForm来创建一个表单的,默认情况下form表单是post提交。当然我们可以改变它,使用Get方法提交也可以。但是我们必须谨慎对待,因为HTTP规范要求Get请求必须是幂等的(idempotent),这意味着不能引起任何改变。我们这里向购物车添加Product显然是一个变化的过程,所以用Post最合适。

补充下:Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是:GET,POST,PUT,DELETE.即查,改,增,删4个操作。针对这个主题(POST提交还是GET提交)下一章会有更多的讲解,还包括了对如果我们忽略了幂等GET请求产生的后果的解释。

接着添加一个样式,如下所示:

View Code

前面我们用Html.BeginForm方法在每一个Product列表创建了Form。这也意味着,每天点击Add to cart按钮时,会提交对应的Form表单。这可能让我们做WebForm的人有点意外,因为WebForm里面限制了每个页面只能有一个Form。但是asp.net mvc里面没有这个限制,完全可以根据我们的需要来创建Form表单。

接着创建CartController用来处理Add to cart按钮点击。代码如下所示:

View Code

在上面的代码里面,AddToCart和RemoveFromCart方法都调用了RedirectToAction方法。这是用来发送重定向的指令到浏览器,让浏览器请求一个新的URL。这里是让浏览器请求一个调用Index action方法的URL。下面实现这个Index方法并用它来展示Cart的内容。

我们需要传递两种信息给展示购物车内容的View,分别是Cart对象和展示当用户点击Continue Shopping按钮时的URL。为此,我们创建一个视图模型的类,在Models文件夹创建CartIndexViewModel的类,代码如下:

View Code

接着实现Cart controller里面的Index action方法,代码如下:

View Code

右键添加视图,如下所示:

Index View的代码如下所示:

View Code

继续添加样式:

View Code

现在基本告一段落,可以运行程序看看效果了。接下来是使用模型绑定(Model Binding)。

asp.net mvc框架使用一种称为model binding的机制将来自HTTP请求创建为C#对象,这样就能够将它们作为参数传递给Controller的Action方法。这也是MVC处理Form表单的原理。例如MVC框架寻找Action方法的参数作为目标,使用model binding从Input元素获取值,并会将这些值转化为Action方法里面参数对应的类型以及相同的参数名称。
Model binders能够将请求里面任何可用的信息创建为C#类型,这是MVC框架一个非常核心的功能之一。

下面我们将创建一个自定义的模型绑定来完善CartController类。这里使用Session对象来存储和管理购物车对象(当然,这可能不符合实际情况,我们只管将注意力放在MVC上吧,呵呵)。

我们将创建一个自定义的绑定来获取包含在Session里面的Cart对象,MVC框架会创建Cart对象并作为参数传递给CartController的Action方法。MVC的model binding功能是非常强大且可伸缩的。对于这个部分,书的第二部分会有详细的讲解。

通过实现IModelBinder接口来创建自定义的model binding。在 SportsStore.WebUI里面创建一个新的文件夹Binders,接着在里面创建CartModelBinder.cs.代码如下:

View Code

IModeBinder接口里面定义一个方法:BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext).提供的两个参数使我们创建领域模型对象成为可能。ControllerContext providers能够访问Controller类的所有信息,包括了来自浏览器的详细请求信息;ModelBindingContext提供我们要创建model object的信息和工具来简化我们的操作。

这里主要关注下ControllerContext类,它有一个HttpContext属性,它包含了Session对象,这正是我们需要的。

我们需要告诉MVC框架使用我们的CartModelBinder类创建Cart的实例,需要修改Global.asax,如下所示:

复制代码
        protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
ModelBinders.Binders.Add(typeof(Cart), new CartModelBinder());
}
复制代码

当MVC收到请求时,比如,AddToCart方法被调用时,它开始寻找action 方法的参数,它将会在可用的绑定列表里面寻找,试图找到一个能够创建每一个参数类型的实例。我们自定义的绑定会被用来创建Cart对象,并且MVC是通过Session功能来实现的。在我们自定义的绑定和默认绑定之间,mvc能够创建必备参数的集合来调用action方法。正是如此才允许我们重构Controller以至于我们不知道在请求被接收时Cart对象是怎样被创立的。

像这样使用自定义的绑定有几个好处:

1.我们将创建购物车的逻辑从Controller里面分离出来,这样就允许我们可以改变存储Cart对象的方式而不必去更改Controller。

2.任何Controller想使用Cart对象,只需要在其Action方法里面声明一个Cart参数即可

3.较好的进行单元测试

下面接着完善购物车功能

这里给购物车增加两个功能:1.允许用户删除购物项 2.在页面顶端增加一个显示购物车详情的功能
首先修改Views/Cart/Index.cshtml,如下所示:

View Code

添加查看购物车详情功能:
在CartController里面添加一个Summary action方法,如下所示:

View Code

Summary方法非常简单,仅仅需要呈现一个View,提供当前购物车作为View Data。当然这里要使用自定义绑定,我需要创建一个partial view。如下所示:

Summary Partial View的代码如下所示:

View Code

因为我们在每个页面都要显示,所有需要在_Layout.cshtml里面进行定义,如下所示:

复制代码
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
<div id="header">
@{Html.RenderAction("Summary", "Cart");}
<div class="title">
Sports Store</div>
</div>
<div id="categories">
@{Html.RenderAction("Menu", "Nav");}
</div>
<div id="content">
@RenderBody()
</div>
</body>
</html>
复制代码

接着添加样式,如下所示:

View Code

这时运行下程序,应该看到如下效果:

好啦,今天的笔记就到这里。请路过的朋友多指导,帮助!
晚安!

本文转自Rt-张雪飞博客园博客,原文链接http://www.cnblogs.com/mszhangxuefei/archive/2012/01/10/mvcnotes_15.html如需转载请自行联系原作者


张雪飞

相关文章
|
2月前
|
API
【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
【Azure 媒体服务】Media Service的编码示例 -- 创建缩略图子画面的.NET代码调试问题
|
4天前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
17 2
|
21天前
|
开发框架 .NET C#
VSCode开发.net项目时调试无效
【9月更文挑战第22天】在使用 VSCode 开发 .NET 项目时遇到调试问题,可从项目配置、调试配置、调试器安装、运行环境、日志和错误信息等方面排查。确认项目类型及文件配置,检查 `launch.json` 文件及配置项,确保调试器扩展已安装并启用,验证 .NET 运行时版本和环境变量,查看 VSCode 输出窗口和项目日志文件,检查权限及代码错误。若问题仍未解决,可查阅官方文档或社区论坛。
|
18天前
|
C#
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
4天前
|
Cloud Native API C#
.NET云原生应用实践(一):从搭建项目框架结构开始
.NET云原生应用实践(一):从搭建项目框架结构开始
|
1月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
31 7
|
2月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
42 8
|
2月前
|
架构师 开发者
【悬念揭秘】DDD:那片隐藏在软件深处的业务乐土——.NET项目如何借力领域驱动设计,让复杂业务逻辑迎刃而解?
【8月更文挑战第28天】领域驱动设计(DDD)在.NET项目中的应用聚焦于将业务领域知识与软件开发紧密结合,通过构建清晰的领域模型管理复杂业务逻辑。DDD的核心概念包括限界上下文、聚合、实体等,确保模型与实现的统一。在.NET中,通过CQRS和事件源等模式提高系统响应性和可扩展性,实现业务事件驱动的解耦与协作。DDD不仅是一种设计方法,更是要求开发者深入理解业务的文化,助力.NET项目应对复杂挑战,实现业务与技术的融合。
55 6
|
2月前
|
设计模式 存储 前端开发
揭秘.NET架构设计模式:如何构建坚不可摧的系统?掌握这些,让你的项目无懈可击!
【8月更文挑战第28天】在软件开发中,设计模式是解决常见问题的经典方案,助力构建可维护、可扩展的系统。本文探讨了.NET中三种关键架构设计模式:MVC、依赖注入与仓储模式,并提供了示例代码。MVC通过模型、视图和控制器分离关注点;依赖注入则通过外部管理组件依赖提升复用性和可测性;仓储模式则统一数据访问接口,分离数据逻辑与业务逻辑。掌握这些模式有助于开发者优化系统架构,提升软件质量。
44 5
|
2月前
|
Kubernetes 监控 Devops
【独家揭秘】.NET项目中的DevOps实践:从代码提交到生产部署,你不知道的那些事!
【8月更文挑战第28天】.NET 项目中的 DevOps 实践贯穿代码提交到生产部署全流程,涵盖健壮的源代码管理、GitFlow 工作流、持续集成与部署、容器化及监控日志记录。通过 Git、CI/CD 工具、Kubernetes 及日志框架的最佳实践应用,显著提升软件开发效率与质量。本文通过具体示例,助力开发者构建高效可靠的 DevOps 流程,确保项目成功交付。
56 0