一步步学习ASP.NET MVC3 (14)——Route路由
请注明转载地址:http://www.cnblogs.com/arhat
由于今天是星期六,所以多写几篇,感觉前几天的忙碌没有及时发布文章,趁着周末老魏尽力的多写几篇文章。因为本系列基本上快结束了,所以老魏也要加把劲了,这个系列完成后,老魏会开始NHibernate,Spring.NET,EF等相关文章的书写。希望大家能够支持一下!
本章老魏主要给大家讲述一下在ASP.NET MVc3中的路由技术,当然本章属于那种不会也会开发ASP.NET MVC的章节,但是老魏还是建议大家要学习一下这个路由技术,这样大家会理解ASP.NET
MVC的生命周期,同时能够避免大家走很多弯路。
当我们创建一个ASP.NET MVC3项目的时候,我们会发现在项目中有一个Global.asax文件,这个文件它包含了ASP.NET应用程序生命周期事件处理,当应用程序启动的时候会先运行这个文件中的Application_Start方法。
我们来看看Global.asax文件的代码:
public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 ); } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } }
当一个ASP.NET MVC应用程序第一次运行时, Application_Start()方法被调用。这个方法,又调用RegisterRoutes()方法,RegisterRoutes()方法创建了路由表。
记得当时老魏在学习路由的时候非常的迷惑,不理解什么是路由,但慢慢的理解什么路由。所谓的路由就是相当于一个路由器,用来分配和匹配用的。比如我们的计算机(A)由路由器分配一个地址“192.168.1.23”,那么如果这个计算机需要访问“192.168.1.128”的计算机(B),那么A计算机需要把他请求的地址发送给路由器,而路由器接收到这地址之后,从路由表中开始查找计算机B的地址,如果B的地址在路由器中的路由表中注册过,则路由器把A的请求发送给B,如果路由器没有找到B在路由表中注册的地址,那么发送不成功!
那么,在ASP.NET MVC中的路由也是这个意思,只不过不是访问的计算机,而是访问的是控制下Action。那么我们可以仿照上面的描述来描述一下ASP.NET MVC的路由过程。比如现在有一个控制器A(/Home/Index)需要访问控制器B(/About/Index)那么,在页面中,我们点击超链接:
<a href=”/About/Index”>About</a>,那么这个超链接将会向服务器发送一个请求,这个请求被Global.asax接收,因为Global.asax中已经注册过了路由,那么则接收到这个请求的时候,路由表中就会查找这个地址”/About/Index”,如果找到了,在开始访问,没有找到则会404。
所以,从上面的描述中,我们知道,在Global.asax的RegisterRoutes方法是用来注册访问路由的。在路由表中注册的路由就是访问的地址规则,如果访问的地址满足了地址规则才会访问,否则错误!
我们可以通过一张图来看一下这个过秤。
从这个图中,我们看到MVC下的请求过程,其实大家也看到了,在这个请求过程中,Global.asax的路由系统起到一个非常重要的作用,那么下面我们来看看它是如何来匹配浏览器发送过来的请求,执行这个请求。
在Global.asax的RegisterRoutes方法中注册了路由规则,这个规则用来匹配浏览器发送过来的请求,默认情况下,这个方法里面已经注册了一个默认的路由。
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 ); }
这个方法中传入一个参数RouteCollection集合,这个集合中就是路由表用来保存路由规则的。通过方法MapRoute方法来增加一条路由规则。这个方法重载了6次,那么根据不同的需求调用不同的方法。那么本章我们将讲解常用的方法,后面的方法我们在后续的章节中讲解。
public static Route MapRoute(this RouteCollection routes, string name, string url); public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults); public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces); public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints); public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces); public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces);
其中,默认路由用的是第二个方法。我们来分析一个这个方法。
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults);
参数:
name:路由的名字
url:路由规则
Defaults:路由的默认值
那么,我们看看默认的路由。
routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 );
首先,路由的名称是Default,路由的规则是"{controller}/{action}/{id}",路由的默认值 new { controller = "Home", action = "Index", id = UrlParameter.Optional }。
我们来分析一下路由的规则,默认的路由规则是"{controller}/{action}/{id}",那么也就是说,浏览器发送过来的请求必须是contrroller开头/action中间/id参数,这样的形式。那么我们写几个来匹配一下。
访问地址:/Home/Index/1 —— /controlller/action/id——匹配
访问地址:/Home/Index——/Controlller/action/id——匹配
访问地址:/Home/Index/apple——/Controlller/action/id——匹配
访问地址:/Home/Index/1/2 —— /controlller/action/id——不匹配
我们用上面的例子来匹配默认的路由,那么通过上面的例子,我们会发现一个问题,为什么第二个和第三个能够匹配成功呢?路由规则中配置了有一个id的参数,怎么没有传递就成功呢?原因是,在默认之中,设置了Id的默认值,所以如果没有传递参数也是可以的。可是为什么传递的apple也能成功呢?因为在http协议中传递的参数类型都是string类型的。
那么,如果现在项目中,没有AboutController控制器,那么我们在浏览器中输入下面的地址:
访问地址:/About/Index —— /controlller/action/id——匹配
首先,访问的地址匹配了路由规则,由于在项目中没有这个控制器,则路由表就找不到对应的控制器去执行,所以回报错。
现在我们来分析一下第三个参数,也就是路由规则的默认值。
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
这个默认值的作用是,如果在浏览器中输入http://localhost,那么将会调用默认的路由规则,同时把默认值作为请求的内容。也就说说,我们访问http://localhost就是访问http://localhost/Home/Index。这个就是默认值的作用。
其实在访问的过程中,最重要的就是默认的规则,只要你访问的地址能够匹配路由规则,则按照路由规则和请求的内容来访问,否则则按照默认值来访问。比如我们访问/About/Index这个地址时候,满足了匹配的规则,那么请求的内容就是AboutController和Index方法,则默认值将不会起作用了。
通过上面的分析,我们明白了路由的作用,那么我们能不能自己添加一个路由规则呢?答案是肯定的,我们可以自定义路由,但是需要注意的是自定义路由必须位于默认路由的前面,因为ASP.NET MVC默认情况下寻找路由的时候是从上到下进行匹配的。
好,我们添加一个路由。
routes.MapRoute( "MyRoute", // 路由名称 "{action}", // 带有参数的 URL new { controller = "About", action = "Index"} // 参数默认值 );
我们添加的这个路由非常的简单,理由名称是MyRoute,路由规则就一个{action},然后下面是默认值,我们的默认值是控制器About,Action为Index没有参数。
那么我们试着猜想一下,如果我们在浏览器中输入http://localhost/Index的时候,是不是访问的是AboutController/Index方法呢?答案是肯定的,因为我们符合了这个规则。
这里我们需要注意的是,默认值中,我们必须设置controller和action的默认值。那么我们在定义一个路由。
routes.MapRoute( "Display", // 路由名称 "Dispaly/{controller}/{action}", // 带有参数的 URL new { controller = "About", action = "Index" } // 参数默认值 );
这个路由的匹配规则是Display/{controller}/{action}那么我们在浏览器中输入下面的地址http://localhost:4878/Display/about/index就是匹配规则的。那么我们在输入一个地址http://localhost:4878/Display/home/index这个地址也是匹配的,不过是这个地址没有用默认值而已。
讲到这里,不知道大家有没有明白路由和自定义路由呢?希望大家能够看得明白,并能够灵活应用起来。
同时,大家可以通过在View中生成ActionLink来做一下测试。但是这里得提醒大家一下,如果没有特别的说明,请不要自定义路由!
一步步学习ASP.NET MVC3 (14)——Route路由的更多相关文章
- 一步步学习ASP.NET MVC3 章节总结
请注明转载地址:http://www.cnblogs.com/arhat 对于<一步步学习ASP.NET MVC3>系列工15章,那么为了方便大家能够快速的预览,老魏在这里为这个系列提供一 ...
- 一步步学习ASP.NET MVC3 (1)——基础知识
请注明转载地址:http://www.cnblogs.com/arhat 首先在这里我想声明一下,这个ASP.NET MVC3系列是我在授课过程中的一些经验,有什么不对的地方,请大家指出,我们共同的学 ...
- 一步步学习ASP.NET MVC3 (3)——Razor(1)
请注明转载地址:http://www.cnblogs.com/arhat 首先这个<一步步学习ASP.NET MVC3>前段时间有些忙,没有顾得上写文章,昨天呢写了3个和ASP.NET的相 ...
- 一步步学习ASP.NET MVC3 (12)——FileResult
请注明转载地址:http://www.cnblogs.com/arhat 忙了两天,本来老魏昨天就应该写出新的文章,但是由于昨天雨夹雪而且加上昨天晚上加了班,到家都没饭吃了,一看时间都9点了,什么饭店 ...
- 一步步学习ASP.NET MVC3 (2)——入门程序
请注明转载地址:http://www.cnblogs.com/arhat 在上一节中,我们只是简单的介绍了什么是MVC及MVC的运行原理.而本节呢,主要来实现下一ASP.NET MVC3的开发流程,并 ...
- 一步步学习ASP.NET MVC3 (5)——View从Action中获得数据
请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们把Razor的模板技术给大家介绍了一下,当然模板中还有其他的知识点,这个以后我们还会继续讲解.本章我们主要讨论 ...
- 一步步学习ASP.NET MVC3 (6)——@helper,@functions
请注明转载地址:http://www.cnblogs.com/arhat 在前一章中,我们讲述了View如何从Action中获得数据,并显示出来,但随着需求的变化,我们可能要对View中显示的数据作出 ...
- 一步步学习ASP.NET MVC3 (7)——Controller,Action,ActionResult
请注明转载地址:http://www.cnblogs.com/arhat 前面几章我们讲解的都是关于View方面的知识,虽然还有很多关于View的知识没有讲,但是没关系,我们在后面使用到的时候在讲解, ...
- 一步步学习ASP.NET MVC3 (13)——HTML辅助方法
请注明转载地址:http://www.cnblogs.com/arhat 今天老魏是在十分郁闷,我的一个U盘丢了,心疼里面的资料啊,全部是老魏辛辛苦苦积攒的Linux资料,太心疼,到现在心情还不是很爽 ...
随机推荐
- JAVA_eclipse 保留Java文件时自动格式化代码和优化Import
Eclipse 保存Java文件时自动格式化代码和优化Import Eclipse中format代码的快捷方式是ctrl+shift+F,如果大家想保存 java文件的时候 自动就格式化代码+消除不必 ...
- 控制器跳转:tabbarcontroller怎么写代码切换视图?
项目中有时候需要在界面中进行跳转 常用的有push present等方法 但想要在tabbarcontroller的某个子控制器跳转到另一个子控制器 怎么做? 只需要一行代码: 1是你需要跳转 ...
- 警告:Pointer is missing a nullability type specifier (__nonnull or __nullable)
当我们定义某个属性的时候 如果当前使用的编译器版本比较高(6.3+)的话经常会遇到这样一个警告: 而且奇怪的是在某些文件中定义这个属性是没有任何警告的 但是在某些文件中定义同样的属性就会报错: 其实 ...
- mysql:通用查询日志general_log
1.通用查询日志:记录建立的客户端连接和执行的语句,通用查询日志默认情况下不是开启的,通用查询日志是以文本方式存放的 当需要采样分析的时候手工开启: SET Global general_log=1; ...
- (转)CentOS 6.5下Redis安装详细步骤
Redis简介:Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作 ...
- CentOS7安装RabbitMQ集群
实验环境 RabbitMQ 集群 server1.example.com IP: 10.10.10.11 Node: diskserver2.example.com IP: 10.1 ...
- 在ef下使用lambda实现left join
db.Categories .GroupJoin( db.Products, Category => Category.CategoryId, Product => Product.Cat ...
- Meteor:用户账号管理添加密码和微博weibo账号系统支持
Meteor账户系统构建与accounts-base包之上,并为publish和methods提供userId的顶层支持.核心包提供的功能有:数据库中的用户记录支持:额外的包提供密码安全验证:第三方登 ...
- 利用sys.dm_db_index_physical_stats查看索引碎片等数据(转)
我们都知道,提高sql server的数据查询速度,最有效的方法,就是为表创建索引,而索引在对数据进行新增,删除,修改的时候,会产生索引碎片,索引碎片多了,就需要重新组织或重新生成索引,以达到索引的最 ...
- @Transactional详解
@Transactional spring 事务注解 默认遇到throw new RuntimeException("...");会回滚需要捕获的throw new Exc ...