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}/")]public ActionResult TestRouting(string a, string b){ViewBag.Name = a;ViewBag.Grade = b;return View();}?
轉載于:https://www.cnblogs.com/May-day/p/8446737.html
總結
以上是生活随笔為你收集整理的MVC路由学习:自定义路由参数(用户看不到参数名),重新定义路由规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷P1919 【模板】A*B Prob
- 下一篇: s3c2440移植MQTT