zoukankan      html  css  js  c++  java
  • 第二节:各种路由约束(动态路由、静态路由、组合路由、正则约束、命名空间约束、区域内路由)

    一. 什么是路由

       路由是约束URL的一组规范,那么什么是URL呢?通俗的来说URL是一个地址,通过该地址,用户可以访问Web网站或者下载服务器上的文件。

         比如下面就是两组URL:

        http://www.cnblogs.com/yaopengfei/p/7828441.html

        http://www.cnblogs.com/yaopengfei/p/7828441

      显然我们喜欢第二组,省略.html,会使该地址看起来更加简洁,更加友好,利于SEO优化。

      那么我们怎么实现这个简单的需求呢?

      答案是:通过【路由】配置,所以现在我们似乎有点清晰了,路由可以规定URL的特殊格式,使其达到特殊效果。

      在ASP.NET MVC框架中,通过路由配置URL,使用户的URL请求可以映射到Controller下的action方法中,执行相应操作,并接受URL中传过来的参数,在MVC5框架中,在【RouteConfig.cs】类中进行路由规则的配置,如下图:

        

    二. 从源码的角度分析路由

       我们进入【RouteConfig】类中,发现核心代码是调用【RouteCollection】类下的MapRoute方法,F12看源码得知,MapRoute方法是RouteCollectionExtensions类的给【RouteCollection】类扩展方法的方法,并且有多个重载,如下图:

      下面分析一下参数的含义:

        (1) name:  要映射的路由的名称。

        (2) url:  路由的 URL 模式,可以自定义路由的格式,可以写静态路由,也可以写动态路由、组合路由等。

        (3) defaults:  一个包含默认路由值的对象,书写路由的默认值。

        (4) constraints: 一组表达式,可以使用正则指定 url 参数值的约束。

        (5) namespaces: 应用程序的一组命名空间,可以缩小检索路由对象匹配的范围。

      底层源码,有兴趣可以看一下:

     1  public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
     2         {
     3             if (routes == null)
     4             {
     5                 throw new ArgumentNullException("routes");
     6             }
     7             if (url == null)
     8             {
     9                 throw new ArgumentNullException("url");
    10             }
    11             Route route = new Route(url, new MvcRouteHandler()) {
    12                 Defaults = CreateRouteValueDictionaryUncached(defaults),
    13                 Constraints = CreateRouteValueDictionaryUncached(constraints),
    14                 DataTokens = new RouteValueDictionary()
    15             };
    16             ConstraintValidation.Validate(route);
    17             if ((namespaces != null) && (namespaces.Length > 0))
    18             {
    19                 route.DataTokens["Namespaces"] = namespaces;
    20             }
    21             routes.Add(name, route);
    22             return route;

    三. MVC中的几类路由及其规则

    1. 动态路由

    1        routes.MapRoute(
    2                 name: "Default",    //路由名称
    3                 url: "{controller}/{action}/{id}",   //路由规则
    4                 defaults: new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默认值,当Controller或action为空(省略)的时候调用
    5             );

    分析:路由规则为 {controller}/{action}/{id} ,其中 {controller}、{action}、{id}为三个参数,/ 为格式分割符号,defaults中声明的是默认路由,所以下面的测试结果:

    http://localhost:7559/

    http://localhost:7559/First

    http://localhost:7559/First/index1

    http://localhost:7559/First/Index1/2

    都会跳转到Index1的页面。

      变种:将上面的代码的URL分割符号稍微调整一下

    1        routes.MapRoute(
    2                name: "Default9",    //路由名称
    3                url: "{controller}/{action}-{id}",   //路由规则
    4                defaults: new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默认值,当Controller或action为空(省略)的时候调用
    5            );

      请求地址就变成了:

    http://localhost:7559/                                               【无法访问】

    http://localhost:7559/First                                        【404找不到】

    http://localhost:7559/First/index1                            【404找不到】

    http://localhost:7559/First/Index1-1                         【可以访问】

     

    2. 静态路由

    1         routes.MapRoute(
    2                 name: "Default2",    //路由名称
    3                 url: "Ypf",   //路由规则,不区分大小写,当输入“ypf”时,会自动跳转到下面的地址
    4                 defaults: new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默认值,当Controller或action为空的时候调用
    5             );

    静态路由:url中是一个静态值,访问的URL只有输入这个静态值,才能访问下面default中的默认值。

    测试地址如下:

    http://localhost:7559/                                            【无法访问】

    http://localhost:7559/ypf                                      【 跳转到index1页面】

    http://localhost:7559/First/index1                       【无法访问】

    补充一下:MapRoute方法是可以不需要写参数名的,就像正常的调用方法一样,所以上面的代码可以改写:

    1             routes.MapRoute(
    2                 "Default3",    //路由名称
    3                 "Ypf",   //路由规则,不区分大小写,当输入“Ypf”时,会自动跳转到下面的地址
    4                  new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默认值,当Controller或action为空的时候调用
    5             );

    3. 组合路由

    1       routes.MapRoute(
    2              "Default4",    //路由名称
    3              "Ypf/{action}",   //路由规则,不区分大小写,规则相符的时候,会自动跳转到下面的地址
    4               new { controller = "First", action = "Index1" }
    5          );

    所谓的组合路由,就是静态路由和动态路由相互组合使用,测试地址如下:

      http://localhost:7559/             【无法访问】       (分析:因为不满足路由规则,没有输入ypf)

      http://localhost:7559/ypf              【 跳转到index1页面】  

      http://localhost:7559/ypf/index1             【 跳转到index1页面】

      http://localhost:7559/Ypf/hh              【404找不到】        (满足路由规则,但是没有hh这个action,所以404)

      http://localhost:7559/ypf/First/index1       【404找不到】        (满足路由规则,但这里把First当做action,并没有这个action,所以404)

    4. 正则约束

    1        routes.MapRoute(
    2                "Default5",
    3                 "{controller}/{action}_{Year}_{Month}_{Day}",
    4                 new { controller = "First", action = "Index1", id = UrlParameter.Optional },
    5                 new { Year = @"^d{4}", Month = @"d{2}", Day = @"d{2}" }
    6             );//正则路由

    所谓的正则约束,是指可以对URL中的参数使用正则表达式进行约束,上述代码约束了Year必须是四位数字,Month和Day必须是两位数字。

    测试地址:

      http://localhost:7559/first/index1_2018_09_01         【跳转到index1页面】

      http://localhost:7559/first/index1         【无法访问】       (分析:因为不满足路由规则,没有输入{Year}_{Month}_{Day} 的参数)

      http://localhost:7559/first/            【无法访问】       (分析:因为不满足路由规则,没有输入{Year}_{Month}_{Day} 的参数

      http://localhost:7559/                【无法访问】        (分析:因为不满足路由规则,没有输入{Year}_{Month}_{Day} 的参数

    5. 命名空间约束

    1         routes.MapRoute(
    2                  name: "Default6",
    3                  url: "{controller}/{action}/{id}",
    4                  defaults: new { controller = "Third", action = "Index", id = UrlParameter.Optional },
    5                  namespaces: new string[] { "Ypf.MVC5" }
    6             );

    所谓的命名空间约束,即限定匹配范围路由的检索范围,提高检索速度。

    特别注意:不能从外层控制器直接跳转到内层Area内的控制器!!

    测试地址:以下三个访问地址,都会跳转到index1页面

      http://localhost:7559/

      http://localhost:7559/First

      http://localhost:7559/First/index1

    6. Area区域内的路由

     1    public override void RegisterArea(AreaRegistrationContext context) 
     2         {
     3             //原路由
     4             //context.MapRoute(
     5             //    "TestOne_default",
     6             //    "TestOne/{controller}/{action}/{id}",
     7             //    new { action = "Index", id = UrlParameter.Optional }
     8             //);
     9 
    10             //结合命名空间进行路由改造
    11             context.MapRoute(
    12                this.AreaName + "_default",
    13                this.AreaName + "/{controller}/{action}/{id}",
    14                new { area = this.AreaName, controller = "Sys_Admin", action = "Index", id = UrlParameter.Optional },
    15                new string[] { "Ypf.MVC5.Areas." + this.AreaName + ".Controllers" }
    16            );
    17 
    18         }

      指MVC5框架中Area区域单独的一套路由规则,我们可以结合区域内的原路由,进行改造一番,如上述代码。

     

  • 相关阅读:
    Algorithm Gossip (48) 上三角、下三角、对称矩阵
    .Algorithm Gossip (47) 多维矩阵转一维矩阵
    Algorithm Gossip (46) 稀疏矩阵存储
    Algorithm Gossip (45) 费氏搜寻法
    Algorithm Gossip (44) 插补搜寻法
    Algorithm Gossip (43) 二分搜寻法
    Algorithm Gossip (42) 循序搜寻法(使用卫兵)
    Algorithm Gossip (41) 基数排序法
    Algorithm Gossip (40) 合并排序法
    AlgorithmGossip (39) 快速排序法 ( 三 )
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7885597.html
Copyright © 2011-2022 走看看