zoukankan      html  css  js  c++  java
  • MVC 路由规则

    一、路由规则说明                                                                                                       

      先来看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" }  //指定优先命名空间
    );
  • 相关阅读:
    RedHat Linux-配置YUM仓库
    04、管道符、重定向与环境变量
    03、新手必须掌握的Linux命令
    size_t
    decltype关键字
    python numpy使用笔记
    Huffman编码
    动态规划(dynamic programming)
    Prim算法
    Kruskal算法
  • 原文地址:https://www.cnblogs.com/feng-NET/p/4542302.html
Copyright © 2011-2022 走看看