开发者社区> 最美的回忆> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介:
+关注继续查看

前面给SportsStore添加了分页的功能。接着我们添加导航控制,通过左边的菜单来分类显示数据。

首先修改SportsStore.WebUI.Models下的ProductsListViewModel.cs,增加一个CurrentCategory属性public string CurrentCategory{get;set;}。
接着修改List action方法,能够通过传入的CurrentCategory来过滤查询的产品列表。修改后的List action方法如下所示:

复制代码
public ViewResult List(string category, int page = 1) { 

            ProductsListViewModel viewModel = new ProductsListViewModel
            {
                Products = repository.Products.Where(p => category == null || p.Category == category)
                .OrderBy(p => p.ProductID)
                .Skip((page - 1) * PageSize)
                .Take(PageSize),
                PagingInfo = new PagingInfo
                {
                    CurrentPage = page,
                    ItemsPerPage = PageSize,
                    TotalItems = category == null ? repository.Products.Count() : repository.Products.Where(e => e.Category == category).Count()
                }
            };
            return View(viewModel);
}
复制代码

通过.where扩展方法我们进行了一个纵向的筛选,将指定Category的Product筛选出来。

重定义URL组合

之前我们看到了一种URl是这样的/?category=Soccer.在webform里面这个是常见的,但是在MVC里面,可以有更加优雅的方式来代替。我们需要修改global.asax.cs里面的RegisterRoutes方法。如下所示:

复制代码
        public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(null,
"",//匹配空的URL
new { controller = "Product", action = "List", category = (string)null, page = 1 }
);

routes.MapRoute(null,
"Page{page}",
new { controller = "Product", action = "List", category = (string)null },
new { page = @"\d+" }//约束:页面必须是数字
);

routes.MapRoute(null,
"{category}",//匹配 /Football or /AnythingWithNoSlash
new { controller = "Product", action = "List", page = 1 }
);

routes.MapRoute(null,
"{category}/Page{page}",//匹配 /Football/Page567
new { controller = "Product", action = "List" },//默认
new { page = @"\d+" }//必须为数字

);
routes.MapRoute(null,
"{category}/Page{page}",//匹配/Football/Page567
new { controller = "Product", action = "List" },//默认
new { page = @"\d+" }//约束
);

routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Product", action = "List", id = UrlParameter.Optional } // 参数默认值
);

}
复制代码

上面的集中组合分别代表以下集中URL的组合:


ASP.NET的路由系统(Routing System)被MVC用来处理来自客户端的请求,但是也会请求向外输出的符合我们URL组合的URL,以及我们能嵌入在web pages里面输出的URL。这样就能够保证URL在我们程序里面是一直不变的。对于路由这块,后面的章节有详细的讲解,所以如果我们这里不太明白,也没关系。

Url.Action方法是我们创建对外输出链接(outgoing links)最方便的一种方式,在List.cshtml里面已经使用过。由于我们需要添加支持对Category的筛选并且把数据传递给helper方法。如下所示:

复制代码
@model SportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "Products";
}
<h2>
Product List</h2>
@foreach (var p in Model.Products)
{
@* <div class="item">
<h3>@p.Name</h3>
@p.Description
<h4>@p.Price.ToString("c")</h4>
</div> *@
Html.RenderPartial("ProductSummary", p);
}
<div class="pager">
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))
</div>
复制代码

分页的链接是形如:http://<myserver>:<port>/Page2 的,这个表示显示所有Product里面的第2页。http://<myserver>:<port>/Chess/Page2这个就会只显示Category为Chess的Product。

绑定一个Category的导航菜单

我们需要显示一个导航的菜单共用户选择,然后显示对应的Product列表。并且我们会在多个Controller里面使用Category的列表,所以我们需要一个独立的,可重用的这样一个Category的列表。在ASP.NET MVC框架里面有子Action(child actions)的概念,对于创建一个可重用的导航控制菜单来说非常合适。child actions需要使用HTML的辅助方法RenderAction,它能够让我们包含一个对应view的action方法的输出。这里,我们可以创建一个新的Controller:NavController,并创建一个Menu的action方法,用来呈现一个导航菜单,并将来自action方法的输出注入到layout里面。

添加NavController,如下所示:

复制代码
    public class NavController : Controller
{
private IProductsRepository repository;
public NavController(IProductsRepository repo)
{
repository = repo;
}

public PartialViewResult Menu(string category=null)
{
ViewBag.SelectedCategory = category;//这里使用的ViewBag将选中的Category传递给View。
IEnumerable<string> categories = repository.Products
.Select(x => x.Category)
.Distinct()
.OrderBy(x => x);
return PartialView(categories);
}
}
复制代码

因为要在所有的页面都使用这个导航菜单,所以需要注入到_layout里面,修改后的_layout如下所示:

复制代码
<!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">
<div class="title">
Sports Store</div>
</div>
<div id="categories">
@{Html.RenderAction("Menu", "Nav");}
</div>
<div id="content">
@RenderBody()
</div>
</body>
</html>
复制代码

Note:RenderAction()跟RenderPartial()一样,都是直接将内容写入Response Stream。

也就是意味着返回值是void,因此也就不能使用Razor里面的“@”标签,而是将它包括在@{}这样一个闭合的块里面。

如果你不喜欢这样,可以使用action方法来替代。
接着添加Menu的view,在Menu Controller上右键添加View,注意:这里的view是一个Partial view,类似webform里面的customer control.如下所示:

复制代码
@model IEnumerable<string>
@{
Layout = null;
}
@Html.ActionLink("Home", "List", "Product")
@foreach (var link in Model)
{
@Html.RouteLink(link, new { controller = "Product", action = "List", category = link, page = 1 },
new { @class = link == ViewBag.SelectedCategory ? "selected" : null })
}
复制代码

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

View Code

在Menu的View里面有这样一个@classe用法,我们在匿名对象里使用@class作为一个新的参数传递给RouteLink方法。这里的“@”不是一个Razor的tag,我们使用了C#里面的一个功能,通过给class添加一个@符合来避免html里面的class和C#里面定义类的关键字class发生冲突。如果这里没有加上@符合,就会被C#编译器认为是定义了一个类。当我们添加了@符合后,编译就知道我们是在匿名类型里面添加的一个参数名为class的参数。这也正好达到了我们的期望。

今天的笔记就到这里。后面会创建简单的购物车,总得来说这个项目实例主要是让我们能够对MVC有一个实际的认识,项目里面一些具体实现,比如分页是全部读出来后分页的。这可能不符合实际的要求,但这不重要。重要的是,通过这个实例对MVC有整体的认识,通过具体操作能够对以后的实际项目的开发积累点经验。如果你是跟着我的笔记操作,出现什么问题,请留言!我是自己已经操作了一遍后,倒过来写笔记的,所以中间的一些步骤我会选择性的舍弃。

晚安!

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


张雪飞

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【小家Spring】Spring MVC容器的web九大组件之---HandlerAdapter源码详解---一篇文章带你读懂返回值处理器HandlerMethodReturnValueHandler (中)
【小家Spring】Spring MVC容器的web九大组件之---HandlerAdapter源码详解---一篇文章带你读懂返回值处理器HandlerMethodReturnValueHandler (中)
52 0
使用Spring MVC统一异常处理实战
使用Spring MVC统一异常处理实战 博客分类:  J2EE Spring Spring MVC 案例文档 SpringMVC异常处理  1 描述  在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。
780 0
开启 Spring & Spring MVC 之旅
不废话了,Spring 有多重要。首先是跑个 Hello World。Spring 最基本功能是 IOC,如果不懂或者好奇原理的可以参考《极简版 Java 依赖注射》。 Hello World 怎么获取 Spring?官方推荐 Maven 依赖管理(据说 Ant 也可以),也可以下载 Java 源码构建。
557 0
spring mvc处理json
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为“中国PE第一股”,市值超1000亿元。
652 0
Spring 3 MVC and JSON example
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为“中国PE第一股”,市值超1000亿元。
653 0
struts2和spring mvc混合使用
     最近有个需求,就是把目前的项目由struts2平滑切换到spring mvc。网上貌似这个资料不是很多,不知道是太简单了,还是没有这种需求。东拼西凑的算是搞定了。分享一下,欢迎拍砖。
1004 0
spring mvc 框架搭建及详解
  现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了。不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理。   一、Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0)
1066 0
Spring MVC 教程,快速入门,深入分析(转载)
作者:赵磊 博客:http://elf8848.iteye.com 下载: Spring的官方下载网址是:http://www.springsource.org/download    (本文使用是的Spring 3.
1283 0
沫沫金:详解Spring MVC模型(Model)层和视图(View)层 推荐
Spring MCV中Model层是View层的数据容器,Jsp页面上所有的参数传递都是通过绑定到模型。 这里不得不说Spring的mvc设计将Entity和Model分离的好处:也许很多SSH开发的程序猿一接触spring的mvc框架感觉这样分离很没有必要,因为struts直接使用Entity就可以了。
890 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Java Spring Boot开发实战系列课程【第7讲】:Spring Boot 2.0安全机制与MVC身份验证实战(Java面试题)
立即下载
蚂蚁金服大数据开放式创新实践
立即下载
FLowFuzz A Framework
立即下载