zoukankan      html  css  js  c++  java
  • MVC5路由系统机制详细讲解

    请求一个ASP.NET mvc的网站和以前的web form是有区别的,ASP.NET MVC框架内部给我们提供了路由机制,当IIS接受到一个请求时,会先看是否请求了一个静态资源(.html,css,js,图片等),这一步是web form和mvc都是一样的,如果不是则说明是请求的是一个动态页面,就会走asp.net的管道,mvc的程序请求都会走路由系统,会映射到一个Controller对应的Action方法,而web form请求动态页面是会查找本地实际存在一个aspx文件。下面通过一个ASP.NET MVC5项目来详细介绍一下APS.NET MVC5路由系统的机制。

    一、认识Global.asax.cs

    当我们创建一个APS.NET MVC5的项目的时候会在项目的根目录中生成一个Global.asax文件。

        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                //注册 路由规则
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
            }
        }

    这个Application_Start方法会在网站启动的自动调用,其中我们看到:RouteConfig.RegisterRoutes(RouteTable.Routes);这个就是向ASP.NET MVC 框架注册我们自定义的路由规则,让之后的URL能够对应到具体的Action。接下来我们再来看看RegisterRoutes方法做了些什么?

        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
            }
        }

    上面代码是vs自动为你们生成,只定义了一个默认规则。
    1、规则名:Default
    2、URL分段:{controller}/{action}/{id},分别有三段,第一段对应controller参数,第段为action参数,第三段为id参数
    3、URL段的默认值:controller为Home,action为Index,id = UrlParameter.Optional表示该参数为可选的。
    之所以我们访问http://www.xx.com/ 这样的URL网址能正确返回,是因为我们设置了URL段的默认值,相当于访问:
    http://www.xx.com/Home/Index

    RegisterRoutes调用的是RouteCollection的MapRoute方法,RouteCollection是一个集合,继承于Collection<RouteBase>

    三、ASP.NET MVC默认的命名约定

    1、Controller命名约定

    Controller类必须以Controller结尾,比如:HomeController,ProductController。我们在页面上用HTML heper来引用一个Controller的时只需要前面Home,Product就可以,ASP.NET MVC框架自带的DefaultControllerFactory自动为我们在结尾加上Controller,并开始根据这个名字开始找对应的类。我们创建一个ASP.NET MVC项目新加的Controller,文件会自动放在根目录的Controllers文件夹里面,我们刚开始可以看到有一个HomeController.cs。当然你也可以实现接口IControllerFactory,定义自己的ControllerFactory来改变查找Controller文件的行为。我会再以后的文章中介绍。

    2、View命名约定

    ASP.NET MVC的视图View默认情况是放在根目录的Views文件下的,规则是这样的:/Views/ControllerName/ActionName.cshtml。比如:HomeController的Action名字为Index的视图对应文件为:/Views/Home/Index.cshtml
    因此是通过Controller和Action的名字来确定视图文件的位置的。采用这个命名约定的好处是在Action返回视图的时候会MVC框架会按照这个约定找到默认的视图文件。比如在ProductController的Action方法List最后是这样的代码:
    return View();
    会自动去路径,/Views/Product/找文件List.cshtml(或者List.aspx如果使用的老的视图引擎)。
    当然也可以指定视图的名字:
    return View("~/Views/Product/List.cshtml")
    或者
    return View("MyOtherView")

    MVC框架在查找具体的默认视图文件时,如果在/Views/ControllerName/下面没有找到,会再在/Views/Shared下面找,如果都没找到就会找错:找不到视图。

    四、ASP.NET MVC的URL规则说明

    最开始我们在网站的Application_Start事件中注册一些路由规则routes.MapRoute,当有请求过来的时候,mvc框架会用这些路由规则去匹配,一旦找到了符合要求就去处理这个URL。例如有下面这个URL:
    http://mysite.com/Admin/Index
    URL可以分为几段,除去主机头和url查询参数,MVC框架是通过/来把URL分隔成几段的。

                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );

    上面表示URL规则是:
    {controller}/{action}
    这个路由规则有两个段,第一个是controller,第二个是action。声明url段每个部分要且{}括起来,相当于占位符,是变量。
    当一个URL请求到来的时候MVC路由系统就负责把它匹配到一个具体的路由规则,并把URL每段的值提取出来。这里说“一个具体的路由规则”,是因为可能会注册多个路由规则,MVC路由系统会根据注册顺序一个一个的查找匹配,直到到为止。
    默认情况,URL路由规则只匹配与之有相同URL段数量的URL。如下表:

    URL
    URL段
    http://mysite.com/Admin/Index
    controller = Admin
    action = Index 
    http://mysite.com/Index/Admin
    controller = Index
    action = Admin 
    http://mysite.com/Apples/Oranges
    controller = Apples
    action = Oranges
    http://mysite.com/Admin
    无匹配-段的数量不够
    http://mysite.com/Admin/Index/Soccer
    无匹配-段的数量超了

    五、mvc创建一个简单的Route规则

    我们在前面注册路由规则都是通过下面的方式:

    public static void RegisterRoutes(RouteCollection routes) {
     
        routes.MapRoute("MyRoute", "{controller}/{action}");
    }

    用到了RouteCollection的MapRoute方法。其实我们还可以调用 Add方法,传一个Route的实例给它一样的达到相同的效果。

    public static void RegisterRoutes(RouteCollection routes) {
     
        Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());
        routes.Add("MyRoute", myRoute);
    }

    六、mvc路由的默认值的设定

    之前有说:URL路由规则只匹配与之有相同URL段数量的URL,这种是严格,但是我们又想有些段不用输入,让用户进入指定的页面。像,http://www.xx.com/Home/就是进入进入Home的Index。只需要设定mvc路由的默认值就可以了。

    public static void RegisterRoutes(RouteCollection routes) {
        routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" });  
    }

    要设置Controller和Action的默认值。

    public static void RegisterRoutes(RouteCollection routes) {
     
    routes.MapRoute("MyRoute", "{controller}/{action}",
            new { controller = "Home", action = "Index" });
    } 

    下面是一个具体的Url对应的Route映射。

    Url段的数量
    实例
    Route映射
    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
    无匹配—Url段过多 

    七、mvc使用静态URL段

    前面定义路由规则都是占位符的形式,{controller}/{action},我们也可以使用在使用静态字符串。如:

    public static void RegisterRoutes(RouteCollection routes) {
     
        routes.MapRoute("MyRoute", "{controller}/{action}",
            new { controller = "Home", action = "Index" });
     
        routes.MapRoute("", "Public/{controller}/{action}",
           new { controller = "Home", action = "Index" });
    }

    上面匹配:http://mydomain.com/Public/Home/Index

    路由:"Public/{controller}/{action}"只匹配有三段的url,第一段必须为Public,第二和第三可以是任何值,分别用于controller和action。
    除此这外,路由规则中可以既包含静态和变量的混合URL段,如:
    public static void RegisterRoutes(RouteCollection routes) {
     
        routes.MapRoute("MyRoute", "{controller}/{action}",
            new { controller = "Home", action = "Index" });
     
        routes.MapRoute("", "Public/{controller}/{action}",
           new { controller = "Home", action = "Index" });
     
    } 

    八、mvc的路由中自定义参数变量

    mvc框架除了可以定义自带的controller和action的参数之外,还可以定义自带的变量。如下:

    public static void RegisterRoutes(RouteCollection routes) {
     
        routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = "1" });
    } 

    id=UrlParameter.Optional设置URL参数可选

    MVC框架从URL获取到变量的值都可以通过RouteData.Values["xx"],这个集合访问。

    九、mvc定义路由规则的约束

    在前面我们介绍了为mvc路由的规则设置路由默认值和可选参数,现在我们再深入一点,我们要约束一下路由规则。

    1、用正则表达式限制asp.net mvc路由规则

    public static void RegisterRoutes(RouteCollection routes) {
     
         routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new { controller = "^H.*"},
            new[] { "URLsAndRoutes.Controllers"});
    }

    上面用到正则表达式来限制asp.net mvc路由规则,表示只匹配contorller名字以H开头的URL。

    2、把asp.net mvc路由规则限制到到具体的值

    public static void RegisterRoutes(RouteCollection routes) {  
     
        routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new { controller = "^H.*", action = "^Index$|^About$"},
            new[] { "URLsAndRoutes.Controllers"});
    } 

    上例在controller和action上都定义了约束,约束是同时起作用是,也就是要同时满足。上面表示只匹配contorller名字以H开头的URL,且action变量的值为Index或者为About的URL。

     3、把asp.net mvc路由规则限制到到提交请求方式(POST、GET)

    public static void RegisterRoutes(RouteCollection routes) {
     
        routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new { controller = "^H.*", action = "Index|About",
                httpMethod = new HttpMethodConstraint("GET") },
            new[] { "URLsAndRoutes.Controllers" });
    }
  • 相关阅读:
    jQuery $.each用法
    《星际穿越》:一手烧脑一手催泪
    onkeyup,onkeydown和onkeypress
    Java 正则表达式
    Java程序员从笨鸟到菜鸟之(十三)java网络通信编程
    Java网络编程
    Java 网络编程
    JAVA的网络编程
    Java集合容器简介
    Java多线程学习(吐血超详细总结)
  • 原文地址:https://www.cnblogs.com/lgxlsm/p/6739533.html
Copyright © 2011-2022 走看看