zoukankan      html  css  js  c++  java
  • MVC路由学习:自定义路由参数(用户看不到参数名),重新定义路由规则

    MVC路由:由于路由global中注册了,在程序第一次运行时,在MVC会自动生成路由,类似于字典的格式缓存下来,但路由生成的规则又是怎样的呢?

    路由生成规则是:

    1》更具你定义的的顺序查找路由规则,如果有匹配的,就会生成路由,生成一条后,不会继续查找下去,结束第一条路由的生成,从而接着一样的方法第二第三条生成

    2》那是怎么查找路由的呢?我们来看下面代码来解释:

                routes.MapRoute(
                    name: "Test",
                    url: "{controller}/{action}/{param1}",
                    defaults: new
                    {
                        controller = "Test",
                        action = "Index",
                        param1 = UrlParameter.Optional,
                    },
                    constraints: new
                    {
                        controller = "^Test.*",
                        action = new ActionConstraints(),// "^transfer.*",
                        param1 = @"d+",
                    }
                );

    1》在这里假设我们当前路由是在顺序的第一,一开始在读取路由规则,都是先读这条,如果你的constraints规则不适应才会寻找下一跳生成路由,如果符合,就会直接生成路由,接着重新遍历这规则,生成下一跳路由

    一,项目有需求将项目地址中的参数名不显示给用户看

    在MVC定义一个方法:

         public ActionResult GetUserInfo(string Name, string Grade)
            {
                ViewBag.Name = Name;
                ViewBag.Grade = Grade;
                return View();
            }

    根据一般请求路径,我们请求的地址为:http://localhost:17273/Home/GetUserInfo?Name=1&Grade=1&Course=1,如果需要不显示参数名,将地址改成这种http://localhost:17273/Home/GetUserInfo/1/1/1形式,而此时我们需要添加路由规则

    1>找到MVC的路由文件RouteConfig.cs

    2>在文件中添加一条路由,如下

                routes.MapRoute(
                   name: "Querylll",
                   url: "{controller}/{action}/{Name}/{Grade}/{Course}",
                   defaults: new
                   {
                       controller = "Home",
                       action = "Index",      
                       Name = UrlParameter.Optional,
                       Course = UrlParameter.Optional
                   },
                   namespaces: new string[] { "RouteDemo.Controllers" }
               );
    
    
    UrlParameter.Optional的定义是允许不传,造成结果是:http://localhost:17273/Home/GetUserInfo/1/1这条路由也是可以寻到该页面
    3>我们定义一个新的方法测试以上结论如下:
         public ActionResult GetList(string Name, string Grade, string Course)
            {
                ViewBag.Name = Name;
                ViewBag.Grade = Grade;
                ViewBag.Course = Course;
                return View();
            }
    PS:但我们需要注意的一点就是:如果你需要第三个字(Course)不为空值,我们必须要传Grade,因为根据路由规则,我们是通过URL的位置匹配参数
    4>那我们使用实体接受是否可以?如下:
           public ActionResult GetListModel(UserName u)
            {
                ViewBag.Name = u.Name;
                ViewBag.Grade = u.Grade;
                ViewBag.Course = u.Course;
                return View();
            }
            public class UserName
            {
                public string Name { get; set; }
                public string Grade { get; set; }
                public string Course { get; set; }
            }    
    
    

    PS:实体的定义也需要符合参数循序和规则

    二,到此时,就有疑问了,如果我们的参数明会变化,那我们不就需要N条路由?这明显不合理,那以上路由就需要改进了,如下

           routes.MapRoute(
                    name: "Query",
                    url: "{controller}/{action}/{param}/{param1}/{param2}",
                    defaults: new
                    {
                        controller = "Home",
                        action = "Index",
                        param = UrlParameter.Optional,
                        param1 = UrlParameter.Optional,
                        param2 = UrlParameter.Optional
                    },
                    namespaces: new string[] { "RouteDemo.Controllers" }
                );

    调用和获取的方法:

         public ActionResult GetListModel(UserName u)
            {
                u.Name = isNull("param") ? u.Name : QueryString("param").ToString();
                u.Grade = isNull("param1") ? u.Grade : QueryString("param1").ToString();
                u.Course = isNull("param2") ? u.Course : QueryString("param2").ToString();
                ViewBag.Name = u.Name;
                ViewBag.Grade = u.Grade;
                ViewBag.Course = u.Course;
                return View();
            }
         public object QueryString(string paramname)
            {
                return System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values[paramname];
    
            }
            public bool isNull(string param)
            {
                return QueryString(param) == null ? true : false;
            }

    PS,这条路由解决了参数定义的顺序问题和参数名字变化等需求问题,若同一个方法有五个参数,但是当被调用时,传如参数可能是1个,2个等情况

    三,那如果我们要写一个路由,只能是某一个控制器,并且是该控制器下某些方法可用,这是路由该怎么定义?如下代码:

             routes.MapRoute(
                    name: "Test",
                    url: "{controller}/{action}/{param1}/{param2}/{param3}/{param4}",
                    defaults: new
                    {
                        controller = "Test",
                        action = "Index",
                        param1 = UrlParameter.Optional,
                        param2 = UrlParameter.Optional, 
                        param3 = UrlParameter.Optional,
                        param4 = UrlParameter.Optional,
                    },
                    constraints: new
                    {
                        controller = "^Test.*",
                        action = new ActionConstraints(),// "^Test.*",
                    }
                );

    我们需要在constrationts定义controllers的默认值即可,action我们就需要使用正则来判断,如下代码

            public class ActionConstraints : IRouteConstraint
            {
                public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
                {
                    string val = values[parameterName].ToString();
                    if (Regex.IsMatch(val, "^Test.*", RegexOptions.IgnoreCase) || Regex.IsMatch(val, "^Index.*", RegexOptions.IgnoreCase))
                    {
                        return true;
                    }
                    return false;
                }
            }
    ^Test.表示当action前缀为Test都返回true,则可以使用这条路由
    PS:如果想以上这种路由没有定义controllers规则,属于主路由,主路由不可以定义在从路由之前,这样如果生成匹配了主路由,从路由就不会生成,则你定义的规则就不会被实现

     四,一个基于属性的路由配置工具使用博客AttributeRouting,可以给特定的action定义路由特定的规则:AttributeRouting 

          [GET("test/ddd/{a}/{b}")]
            public ActionResult TestRouting(string a, string b)
            {
                ViewBag.Name = a;
                ViewBag.Grade = b;
                return View();
            }
  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/May-day/p/8446737.html
Copyright © 2011-2022 走看看