一、路由规则说明

  先来看MVC中的默认路由的说明

"{controller}/{action}/{id}", // URL with parameters
  对于Url  /Home/Index/1
  匹配结果是:
  controller  :  "Home"
  action    :  "Index"
  Id      :  "1"
  
  对于Url  /a.b/c-d/e-f
  匹配结果是:
  controller  :  "a.b"
  action     :  "c-d"
  Id       :  "e-f"

  为了Asp.net MVC框架的正常运行,框架要求使用一些特定的参数名称{controller}和{action}。

  假设我们想让所有的MVC请求都以site开头,那么路由我们可以改成这样

  site/{controller}/{action}/{id}

  假设想让所有的页面都以.aspx为后缀,则可以这样写

{controller}/{action}.aspx/{id}

  现在来将Global.asax.cs的路由复制出来解释一下

    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}", // 带参数的匹配规则
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 默认参数,即当不输入时间的处理方法
);
} protected void Application_Start()
{
       //这里还可以加一行
       RouteTable.Routes.RouteExistingFiles = true;  //如果设为true,这行表示,该网站所有的HTTP请求都会使用RegisterRoutes()方法中定义的网址里有规则一一进行比对,如果对比成功就会用Asp.net Mvc进行处理,若对比失败,再检查磁盘上的文件。默认是false的,因为Html文件,css,js文件等可以优先不经过路由直接显示。
AreaRegistration.RegisterAllAreas();
      
RegisterGlobalFilters(GlobalFilters.Filters);
       //注册前面定义的路由,所有的Asp.net MVCRouting都在此定义,其中参数RouteTable.Routes是一个公开的静态对象,存储了所有的Routing规则集(RouteCollection类)
RegisterRoutes(RouteTable.Routes);
}
}

  1、IgnoreRoute  不理会的路由说白了就是用来定义不需要通过Routing处理的网址。

    例如:http://localhost/Trace.axd  

    OK,该条路径匹配成功{resource}.axd比对到Trace.axd。而{*pathInfo}比对到空。因此匹配成功。匹配成功就怎么样呢?Ignore,不处理。也就是,上面那条Url是不会被Asp.net MVC处理的。

  2、MapRoute()  最常用来定义Routing规则的辅助方法。用于定义一条路由。其中第一个参数是路由名称,第二个参数是Url以及参数,第三个是默认值。

  3、我们之前看到个  *  号,它表示Catch-All。即不管什么乱七八糟的东西都匹配。没有就匹配空。

  4、UrlParameter.Optional  指定可选参数的默认值,当不填写的时候,不会添加进参数字典。

二、自定义路由

routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}/{age}/{birthday}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional ,
age=18 ,birthday=new DateTime(1989,1,1) }, // 参数默认值
); public ActionResult Index( string id , int age , DateTime birthday)
{
return View();
}
  如果我们在路由中定义了定义好了包含这三个参数的模式,然后输入正确的URL后,路由系统就会自动从中提取出controller , action ,以及这三个参数(如果参数名匹配,并且能够完成类型转换的话)。
  例如,我们输入http://localhost/User/Getinfo/123344/24/1989-9-16 ,路由就会提取出一下信息 ,controller=User ,action = Getinfo,
id=123344 , age=24 ,birthday=1989-9-16

三、定义可变长度的参数的路由

 routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}/{*catchall}", // 带有不定个数的参数的 URL
new { controller = "Home", action = "Index",
id=UrlParameter.Optional }, // 参数默认值
);
   这个路由能匹配所有的URL。具体匹配情况如下图:
      

序号 URL 示例 映射结果
0 mydomain.com  controller=home,action=index
1 mydomain.com/Customer  controller=Customer,action=index
2 mydomain.com/Customer/List  controller=Customer,action=List
3 mydomain.com/Customer/List/All  controller=Customer,action=List,id=All
4 mydomain.com/Customer/List/All/Delete  controller=Customer,action=List,id=All,catchall=Delete
5 mydomain.com/Customer/List/All/Delete/Perm  controller=Customer,action=List,id=All,catchall=Delete/Perm
 

四. 定义命名空间的优先级

  根据以上内容我们已经知道,当URL匹配上一个路由之后,就会提取路由中的信息,然后进行进一步处理。假如现在我们的某个路由提取出了一个controller为Account ,并且我们的解决方案中有不只一个名为“AccountController”的类,由于路由并不知道要调用哪个controller ,这个时候就会出现错误。那么,如何解决这种问题呢?我们可以在注册路由的时候,指定某个路由有限查找controller 的命名空间,如下面的代码所示。

 routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index",
id = UrlParameter.Optional }, // 参数默认值
new string[] { "MyNamespace.Controllers" } //指定优先命名空间
);

五、路由约束

  我们可以给URL的匹配加上以下限制:
        a, 正则表达式
        b,HTTP method

  routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional }, // 参数默认值
//设置匹配约束
new {controller = "^H.*" , action ="^Index$|^About&" ,     //必须要被正则表达式成功匹配,才使用该路由
httpMethod=new HttpMethodConstrain("Get") }   //指定只使用Get方法的请求才会被匹配
);
  这个路由就要求,controller的值必须是以字母"H"开头的,并且action只能是Index 或者 About ,并且只能用Get方式。
    如果这些系统定义的约束条件不能满足项目的需求,我们可以自定义约束条件,只要实现 IRouteConstraint 接口 ,然后将该类的一个实例传给routs就可以了。代码如下:

public class UserConstrain : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
return true ; //你可以在这里做具体的操作
}
} routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id
=UrlParameter.Optional }, // 参数默认值
new {controller = "^H.*" , action ="^Index$|^About&" ,
httpMethod=new HttpMethodConstrain("Get") ,
customConstrain= new UserConstrain () } , //设置匹配约束
new string[] { "MyNamespace.Controllers" } //指定优先命名空间
);

MVC 路由规则的更多相关文章

  1. 【基础】MVC路由规则

    一.RouteData解析过程 在ASP.NET MVC中,服务器收到来自客户端的请求后,会经过一些列的处理拿到请求的数据,比如在Pipeline 管线事件中,通过订阅适当的事件,将HttpConte ...

  2. MVC路由规则进一步了解

    本周由于工作需要,接触了PetaPoco(一个小型的ORM-框架)和ExtJS,这个项目框架是别人写好的,用的是MVC,我写的MVC程序一般控制器和视图都是在一个类库下面的,但是作者是把MVC中的控制 ...

  3. ASP.NET MVC路由规则

    1 是从上往下寻找路由规则的 2 如果上面的匹配了,则下面的不会匹配 3 假如域名是www.startpress.cn 路由规则是 routes.MapRoute( name: "Defau ...

  4. mvc路由规则相关

    1,可以创建多条路由规则,每条路由规则的name属性不能相同 2,路由规则是有顺序的,如果被前面的规则匹配了,那么后面的规则就没有机会了 下面是一条路由规则的代码 routes.MapRoute( n ...

  5. MVC路由规则以及前后台获取Action、Controller、ID名方法

    1.前后台获取Action.Controller.ID名方法 前台页面:ViewContext.RouteData.Values["Action"].ToString(); Vie ...

  6. MVC路由规则

    1 可以创建多条路由规则,每条路由规则的那么属性不同 2路由规则是有顺序的.如果被前面的规则匹配了,那么后面的规则就没机会了 3 constraints 约束: 4namespaces 命名空间 5r ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)

    前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...

  8. mvc中多参数URL会很长,首次加载不传参数让url很短,路由规则实现方法[bubuko.com]

    如要实现列表中地址全路径“bubuko-11-2.html”,在首次进入时,使用短路径“bubuko.html”,只有再次href后才显示全路径“bubuko-11-2.html”,下面使用路由规则来 ...

  9. MVC之路由规则 (自定义,约束,debug)

    自定义路由规则的要求,小范围写在前,大范围写在后.路由规则可以注册多条,路由规则的名称不能重复路由规则有顺序,并且按照顺序进行匹配,建议小范围写在前,大范围写在后.路由规则可以设置约束 即正则表达式路 ...

随机推荐

  1. spring常用的连接池属性文件配置

    (一) DBCP 引入jar文件 commons-dbcp-1.2.1.jar commons-pool-1.3.jar二个包. spring配置文件 <bean id="dataSo ...

  2. global, $GLOBALS[]

    // global在函数中产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一旦改变了别名的变量指向地址,就会发生一些意外的情况 $a = 10; function test() { gl ...

  3. 还原数据库备份文件时,关于“System.Data.SqlClient.SqlError:媒体集有2个媒体簇,但只提供了1个。必须提供所有成员”的处理方式

    好久没写博客了,最近在做毕设的权限管理模块,今天在还原数据库文件时,遇到了“System.Data.SqlClient.SqlError:媒体集有2个媒体簇,但只提供了1个.必须提供所有成员”这个错误 ...

  4. 图片裁切插件jCrop的使用心得(四)

    在本篇中我来介绍一下jcrop如何实时展现用户裁切的效果图以及在项目中使用该插件注意的问题. 首先,你们在创建头像时,都可以在旁边实时的看到我裁切后的效果图,就如博客园. 这个是如何实现的呢,其实并不 ...

  5. Python Mixin混入的使用方法

    DEMO # encoding=utf-8 __author__ = 'kevinlu1010@qq.com' class Base(): def f1(self): print 'I am f1 i ...

  6. Chart Style

    How to add label to column chart http://blogs.msdn.com/b/delay/archive/2009/07/27/simple-column-labe ...

  7. 【web安全】第六弹:手工SQL注入详解

    前一段时间,在对SQL注入有了新的理解之后,写了这篇文章.本来准备投稿,因为内容过于基础被打回来了,想想屯着也没意思,发出来发出来~~本来有好多图的,但是博客园发图很麻烦,word文档的链接会贴在文章 ...

  8. Runtime - 01

    Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西.最近在学习Runtime,有自己的一些心得,整理如下, 什么是Runtime 我们写的代码在程序运行过程中都会 ...

  9. bzoj 3672: [Noi2014]购票 树链剖分+维护凸包

    3672: [Noi2014]购票 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 480  Solved: 212[Submit][Status][D ...

  10. [cc150] 硬币问题

    Given an infinite number of quarters (25 cents), dimes (10 cents), nickels (5 cents) and pennies (1 ...