• 4.路由学习


    1.路由学习

    2.路由源码解读

    3.自定义路由

    在MVC的项目中有一个Global.asax.cs 文件,里面有一个 Application_Start 方法,代码如下:

    public class MvcApplication : System.Web.HttpApplication
        {
            /// <summary>
            ///不是每次请求都调用
            ///在Web应用程序的生命周期里就执行一次
            ///在应用程序第一次启动和应用程序域创建时被调用
            ///适合处理应用程序范围的初始化代码
            /// </summary>
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由
                BundleConfig.RegisterBundles(BundleTable.Bundles);
            }
        }

    这个地方就是开启路由的地方,它把url包装成Route对象,然后把我们注册的路由规则用name---route键值对的方式存入RouteCollection中(注册的路由写在App_Start 文件加下面的 RouteConfig 里面),当请求来了后,会在RouteCollection进行路由解析,就会根据自定义的路由规则从上到下进行匹配

    路由解析:

      1.如果没有匹配上我们定义的路由,那么就走原始流程,就等于MVC中路由完全没有生效

      2.如果请求能够找到物理文件,那么就不再匹配路由(支持WebForm的原因)

      3.匹配路由是从上到下进行匹配的,如果第一个匹配上了,那么就不会继续往下匹配了,如果匹配不上,那么就走原始流程

    WebForm请求:

      WebForm请求的是一个具体的页面,当用户请求具体的aspx页面时,服务器会对该页面中的内容一行一行的解析(碰到服务器脚本语言还会执行),最后形成响应流重新写回到浏览器,再由浏览器对该响应流进行解析(依照W3C标准),最终将用户请求的页面呈现出来

    注册路由的几种方式如下:

      1.在RouteConfig 里面注册路由

        参数说明:

          name:          路由名称
          url:     url参数
          defaults:    参数默认值
          constraints:  参数约束(常用的是正则表达式)

    /*
                    默认路由规则
                    这个表示只匹配所有控制器下面的动作,如果不指定控制器和动作,那么默认访问Home控制器下的Index动作,如果指定了,那么就访问指定的控制器下的动作
                */
                routes.MapRoute(
                    name: "Default1",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
    
                /*
                   指定控制器(就是把控制器写死)
                   这个表示只匹配Home控制器下面的动作,如果不指定动作,那么默认访问Index动作,如果指定了,那么就访问指定的动作
               */
                routes.MapRoute(
                    name: "Default2",
                    url: "Home/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
    
                /*
                   指定控制器和动作(就是把控制器和动作写死)
                   这个表示只匹配Home控制器下面Index动作
                */
                routes.MapRoute(
                    name: "Default3",
                    url: "Home/Index/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
    
                /*
                     给路由定义约束(constraints)
                     这个表示只能匹配Home和Index控制器下面的Index方法
                */
                routes.MapRoute(
                    name: "Default4",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                    constraints: new { controller = "Home|Index", action = "Index" }
                );
    
    
                /*
                     给路由定义约束(constraints)
                     这个表示只能匹配Home和Index控制器下面的Index方法,并且一定要带一个参数 id,不管动作是否需要参数,不带访问不到啊(例如:localhost:8955/Index/Index_100)
                     这样写的好处是GET请求的时,让别人不知到你这参数是干什么的,是什么字段
                     注意:
                        这个地方可以随意拼接例如:{controller}_{id}/{action}   {controller}/{action}/_{id} 
                */
                routes.MapRoute(
                    name: "Default4",
                    url: "{controller}/{action}/_{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                    constraints: new { controller = "Home|Index", action = "Index" }
                );
    
    
                /*
                     给路由定义约束(constraints)----正则表达式
                     这个表示
                        1.只能匹配Home和Index控制器下面的Index方法,并且一定要带一个参数 id,
                        2.并且id的值是五个数字组成 (例如:localhost:8955/Home/Index_10000)
                        3.此路有之匹配GET请求 
                */
                routes.MapRoute(
                    name: "Default4",
                    url: "{controller}/{action}_{id}",
                    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                    constraints: new { controller = "Home|Index", action = "Index",id=@"d{5}",httpMethod = new HttpMethodConstraint("GET") }
                );
    View Code

      2.使用特性注册路由(RouteAttribute)

        使用:

          首先我们在RouteConfig 里面启动特性路由,将特性 RouteAttribute 标记到控制器或控制器操作上。

    public static void RegisterRoutes(RouteCollection routes)
    {
        /*
            IgnoreRoute为RouteCollection 的扩展方法,作用是忽略指定样式的路由。 
            上面routes.IgnoreRoute("{resource}.axd/{*pathInfo}");中的{resource}代表一个路由参数,
            上面routes.IgnoreRoute("{resource}.axd/{*pathInfo}");中的{resource}代表一个路由参数,
            { resource}.axd代表以.axd结尾的字符串;{*pathInfo}也是一个路由参数,*代表匹配任何字符串,
            那么以pathInfo结尾的串都会匹配到。这条语句完整含义是:以axd结尾的任何字符串,不论斜杠后是何种字符串都不执行路由行为。
        */
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapMvcAttributeRoutes();//启动路由
    }

        使用特性的三个属性或构造函数:

           public RouteAttribute(string template):template是路由匹配模式

           Name:获取或设置路由名称

           Order:获取或设置路由应用顺序

           Template:获取路由匹配模式

    public class HomeController : Controller
        {
            /// <summary>
            /// url:localhost:8955/Home/Index
            /// </summary>
            [RouteAttribute("Home/Index")]
            public ActionResult Index()
            {
                return View();
            }
    
            /// <summary>
            /// url:localhost:8955/Home-Index
            /// </summary>
            [RouteAttribute("Home-Index")]
            public ActionResult Index()
            {
                return View();
            }
    
            /// <summary>
            /// url:localhost:8955/Home/aaa
            /// </summary>
            [RouteAttribute("Home/aaa")]
            public ActionResult Index()
            {
                return View();
            }
    
            /// <summary>
            /// url:localhost:8955/Home/10-10
            /// 注意:
            ///     如果动作里面有2个参数,此参数是无任何类型的 a b(public ActionResult Index(int a, int b)),那么参数a为10,参数b为10
            ///     不管动作是否有参数,都需要传递值进来(不能 localhost:8955/Home)
            /// </summary>
            [RouteAttribute("Home/{a}-{b}")]
            public ActionResult Index(int a, int b)
            {
                return View();
            }
    
    
            /// <summary>
            /// url:localhost:8955/Home/10-10
            /// 注意:
            ///     不管动作是否有参数,都需要传递值进来(不能 localhost:8955/Home)
            ///     a 无任何类型   b 只接受int类型的值(如果要接受时间类型:{b:datetime})
            /// </summary>
            [RouteAttribute("Home/{a}-{b:int}")]
            public ActionResult Index()
            {
                return View();
            }
    
            
    
            [RouteAttribute("Home/Main")]
            public ActionResult Main()
            {
                return View();
            }
        }
    View Code

    当然,因为在同一个控制器中,所有动作的控制器的名称都是一样的,所以我们可以在控制器上面使用RoutePrefix定义公共路由

    当然需要更加了解可以访问:https://www.cnblogs.com/ITusk/p/7677001.html

    namespace WebApplication1.Controllers
    {
        [RoutePrefixAttribute("Home/{id}")]
        public class HomeController : Controller
        {
            /// <summary>
            /// url:localhost:8955/Home/15/Index
            /// </summary>
            [RouteAttribute("Index")]
            public ActionResult Index()
            {
                return View();
            }
        }
    }

    我们可以使用 ? 将一个路由参数标记为 可选参数(optional parameter),如果一个路由参数被标记为可选的,则必须为其设置默认值

    [Route("api/product/{id:int?}")]
    public IHttpActionResult GetProduct(int id =1){
    }

     可以同时使用多个约束条件,每个条件之间通过 进行分割,例如

    [Route("api/product/{id:int:min(1)}")]
    public IHttpActionResult GetProduct(int id){}

     

    课外补充:

     URL与搜索引擎优化
                1)URL越短越好

                2)用破折号而不是下划线

                3)使用小写字母。根据HTTP规范,URL区分大小写,一般的搜索引擎遵循HTTP规范

            Glimpse:
            使用Glimpse观察路由
                安装:打开VS->工具->NuGet程序包管理器->搜索Glimpse.MVC5,然后回车,执行安装
                使用:

          1.运行web应用,输入地址格式为:网站根目录/glimpse.axd,例如   localhost:8955/glimpse.axd

          2.点击页面中的Turn Glimpse On 按钮

          3.运行你要测试页面地址

     

     

  • 相关阅读:
    ASP.NET Core教程:ASP.NET Core使用AutoMapper
    C#:C#调用WebService
    EntityFrameworkCore教程:更新时间映射
    EntityFrameworkCore教程:表名映射
    EntityFrameworkCore教程:Data-Seeding(种子数据)
    EntityFrameworkCore教程:生成数据库表
    EntityFrameworkCore教程:单元测试
    OAF_文件系列5_实现OAF解析XML文件javax.xml.parsers(案例)
    OAF_文件系列4_实现OAF上传显示数据库动态图片Image(案例)
    OAF_文件系列3_实现OAF多行表中附件功能AttachmentImage(案例)
  • 原文地址:https://www.cnblogs.com/zjdbk/p/10617280.html
Copyright © 2020-2023  润新知