在之前的章节,偶们设置了核心的基础设施,现在我们将使用基础设计添加关键特性,你将会看到投资是如何回报的。我们能够很简单很容易地添加重要的面向客户的特性。沿途,你也会看到一些MVC框架提供的附加的特性。

1 添加导航控件

如果使用分类导航,需要做以下三个方面:

  • 增强List action模型,让它能过滤repository中的Product对象
  • 重访并增强URL方案,修改我们的重路由策略
  • 创建sidebar风格的分类列表,高亮当前分类,并链接其它分类

1.1 过滤Product列表

偶们要增强视图模型类ProductViewModel。为了渲染sidebar,我们要传送当前分类给view。

}

我们给视图模型新增了CurrentCategory属性,下一步是更新ProductController类,让List action方法会以分类过滤Product对象,并是我用我们新增的属性指示那个分类被选中。

}

我们修改了三个部分。第一,我们添加一个叫做category的参数。第二,改进Linq查询,如果category不是Null,仅匹配Category属性的Product对象被选择。最后一个改变是设置CurrentCategory的属性。这些变化会导致不能正确计算TotalItems的值。

1.2 更新已存在的单元测试

我们修改了List action方法的签名,它会放置一些已经存在的单元测试方法被编译。为了解决此事,传递null作为List方法的第一个参数。例如Can_Send_Pagination_View_Model,会变成这样

).Model;

通过使用null,我们像以前一样,得到了全部的repository。

1.3 分类过滤单元测试

}

1.4 改善URL方案

没有人像看到或使用丑陋的URLs,如/?category=Soccer。

}

路由添加的顺序是很重要的。如果改变顺序,会有意想不到的效果。

URL Leads To
/ 显示所有分类的products列表的第一页
/Page2 显示所有类别的items列表的第二页
/Soccer 显示指定分类的items列表的第一页
/Soccer/Page2 显示指定分类的items列表的指定页
/Anything/Else 调用Anything controller的Else action

路由系统既能处理来自客户端的请求,也能处理我们发出的URLs请求。

Url.Action方法是生成外向链接的最方便的方式。之前,我们用它来显示Page links,现在,为了分类过滤,需要传递这个信息给helper方法。

new { id=x,category=Model.CurrentCategory}))

通过传递CurrentCategory我们生成的URL不会丢失分类过滤信息。

2 构建分类导航目录

我们会在多个controllers中用到这个分类列表,所以它应该独立,并可以重用。MVC框架有child action的概念,特别适合用来创建可重用的导航控件。Child Action依赖RenderAction这个HTML helper方法,它能让你在当前view中包含数量的action方法的输出。

这个方法给我们一个真实的controller,包含任何我们需要的程序逻辑,并能像其他controller一样单元测试。这确实是一个不错的方法,创建程序的小片段,保持整个MVC框架的方法。

2.1 创建导航控件

需要创建一个新的NavController controller,Menu action,用来渲染导航目录,并将方法的输出注入到layout。

}

要想在layout中渲染child action,编辑_Layout.cshtml文件,调用RenderAction help方法。

</div>

RenderAction方法直接将content写入response流,像RenderPartial方法一样。这意味着方法返回void,它不能使用常规的Razor@tag。我们必须在Razor代码块中闭合调用方法,并使用分号终止声明。也可以使用Action方法,如果不喜欢代码块语法。

2.2 生成分类列表

我们不想在controller中生成URLs,我们用helper方法来做这些。所有我们要在Menu action方法中做的,就是创建一个分类列表:

}

Menu action方法很简单,它只用Linq查询,获得分类的名字的列表,并传输他们到视图。

2.3 生成分类列表的单元测试

我们的目标是要生成一个按字母表排列的没有重复项的列表。最简单的方式,是提供含有重复分类的,没有排列顺序的测试数据,传递给NavController,断言数据已经处理了干净了。

}

2.4 创建部分视图

视图名Menu,选中创建部分视图,模型类填IEnumerable<string>

}

我们添加叫做Home的链接,会显示在分类列表的顶部,让和用户返回到没有分类过滤的,所有products列表的首页。为了做到这点,使用了ActionLink helper方法,使用偶们早前配置的路由信息生成HTML anchor元素。

然后枚举分类名字,使用RouteLink方法为他们创建连接。有点像ActionLink,但它让我们提供一组name/value pairs,当从路由配置生成URL时。

2.4 高亮当前分类

一般我们会创建一个包含分类列表和被选中的分类的视图模型。但是这次,我们展示View Bag特性。这个特性允许我们不使用视图模型,从controller传递数据到view。

}

我们添加给Menu action方法添加了category参数,它由路由配置自动提供。我们给View的ViewBag动态创建了SelectedCategory属性,并设置它的值。ViewBag是一个动态对象。

2.5 报告被选中分类的单元测试

通过读取ViewBag中属性的值,我们可以测试Menu action方法是否正确地添加了被选中分类的细节。

}

我们不需要转换ViewBag属性的值,这是相对于ViewData先进的地方。

}

在Menu.cshtml局部视图中的@html.RouteLink增加第三个参数。第一个参数是string linkText,第二个参数是object routeValues,第三个参数是object htmlAttributes。当前选中的分类会被指派 selected CSS类。

注意在匿名对象中的@class,作为新参数传递给RouteLink helper方法。它不是Razor tag。HTML使用class给元素指派CSS样式,C#使用class创建class。我们使用了C#特性,避免与HTML关键字class冲突。@符号允许我们使用保留的关键字。如果我们仅调用class参数,不加@,编译器会假设我们定义了一个新的C#类型。当我们使用@符号,编译器会知道我们想要创建在匿名类型中创建一个叫做class的参数。

2.6 修正页面总数

当前,页数指向所有的产品。当使用分类后,页数应不同。我们可以通过更新List action方法的ProductController,修复它。分页信息携带分类到总数。

repository.Products.Where(e=>e.Category==category).Count()

如果分类被选中,我们返回这个分类的items数。如果没有选中,返回总数。

}

【Pro ASP.NET MVC 3 Framework】.学习笔记.6.SportsStore:导航的更多相关文章

  1. Pro ASP.NET MVC 5 Framework.学习笔记.6.3.MVC的必备工具

    每个MVC程序员的军火库中,都有这三个工具:一个依赖注入(DI)容器,一个单元测试框架,一个模拟工具. 1.准备一个示例项目 创建一个ASP.NET MVC Web Application的Empty ...

  2. Pro ASP.NET MVC 5 Framework.学习笔记.6.4.MVC的必备工具

    2.5.创建链式依赖 当你请求Ninject创建一个类型,它检查该类型的依赖是否声明.它也会检查该依赖是否依赖其他类型.如果这里有附加依赖,Ninject自动解决他们,并创建请求的所有类的实例.正是由 ...

  3. ASP.NET MVC Web API 学习笔记---第一个Web API程序

    http://www.cnblogs.com/qingyuan/archive/2012/10/12/2720824.html GetListAll /api/Contact GetListBySex ...

  4. 【Pro ASP.NET MVC 3 Framework】.学习笔记.11.ASP.NET MVC3的细节:概览MVC项目

    书Adam The Definitive Guide to HTML5 Adam Applied ASP.NET 4 in Context and Pro ASP.NET 4 到此为止,我们已经学了为 ...

  5. 【Pro ASP.NET MVC 3 Framework】.学习笔记.12.ASP.NET MVC3的细节:URLs,Routing和Areas

    Adam Applied ASP.NET 4 in Context 1 介绍Routing系统 在引入MVC之前,ASP.NET假定被请求的URLs和服务器硬盘上的文件之间有着直接关系.服务器的任务是 ...

  6. 【Pro ASP.NET MVC 3 Framework】.学习笔记.9.SportsStore:Securing the Administration Features

    1 设置表单身份认证 因为ASP.NET MVC基于ASP.NET平台的核心,所以我们可以使用ASP.NET Form的身份认证,这是保持用户登录轨迹通用的方法.现在介绍最基本的配置. 在Web.co ...

  7. 【Pro ASP.NET MVC 3 Framework】.学习笔记.7.SportsStore:购物车

    3 创建购物车 每个商品旁边都要显示Add to cart按钮.点击按钮后,会显示客户已经选中的商品的摘要,包括总金额.在购物车里,用户可以点击继续购物按钮返回product目录.也可以点击Check ...

  8. ASP.Net MVC开发基础学习笔记:一、走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  9. ASP.Net MVC开发基础学习笔记(1):走向MVC模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  10. ASP.NET MVC 5 系列 学习笔记 目录 (持续更新...)

    前言: 记得当初培训的时候,学习的还是ASP.NET,现在回想一下,图片水印.统计人数.过滤器....HttpHandler是多么的经典! 不过后来接触到了MVC,便立马爱上了它.Model-View ...

随机推荐

  1. C3P0的详细配置说明

    C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSourc ...

  2. T4教程1 T4模版引擎之基础入门

    T4模版引擎之基础入门   额,T4好陌生的名字,和NuGet一样很悲催,不为世人所熟知,却又在背后默默无闻的奉献着,直到现在我们项目组的人除了我之外,其它人还是对其豪无兴趣,基本上是连看一眼都懒得看 ...

  3. 框架基础——全面解析Java注解

    为什么学习注解? 学习注解有什么好处? 学完能做什么? 答:1. 能够读懂别人写的代码,特别是框架相关的代码: 2. 让编程更加简洁,代码更加清晰: 3. 让别人高看一眼. spring.mybati ...

  4. MongoDB ObjectId

    概述 > db.col.find() { , } { , } { , } { , } 每个文档中都有一个“_id”,她是一个12字节的BSON类型数据,格式如下 56c56dd4ca446fab ...

  5. Rman备份的保留策略(retention policy)

    什么是备份的保留策略(retention policy) 保留策略就是指某份备份是否要保留以及保留多久.可以使用configure retention policy命令来创建一个一致的.自动的备份保留 ...

  6. Java基础之处理事件——应用程序中的语义事件监听器(Sketcher 5 with element color listeners)

    控制台程序. 为了标识元素的类型,可以为菜单已提供的4中元素定义常量,用作ID.这有助于执行菜单项监听器的操作,还提供了一种标识颜色类型的方式.我们会累积许多应用程序范围的常量,所以把它们定义为可以静 ...

  7. HTML语言的一些元素(二)

    3)表示元素:<b>,<i>,<u>,<s>,<tt>,<sup>,<sub>,<strike>,< ...

  8. C#删除xml中某个节点的子节点方法

    if (File.Exists(xmlFilePath)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlFilePath); Xm ...

  9. UML: 序列图

    摘自http://www.umlonline.org/school/thread-37-1-1.html 大家都进过餐馆吃饭吧?你是如何和餐厅服务员“眉来眼去”的呢?回忆一下从你进餐馆开始到你离开餐馆 ...

  10. html5文件上传

    <!DOCTYPE html><html><head> <title>Html5 Ajax 上传文件</title></head> ...