中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么給ASP.NET MVC及WebApi添加路由優先級

發布時間:2021-08-18 10:25:48 來源:億速云 閱讀:108 作者:chen 欄目:編程語言

本篇內容介紹了“怎么給ASP.NET MVC及WebApi添加路由優先級”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、為什么需要路由優先級

大家都知道我們在Asp.Net  MVC項目或WebApi項目中注冊路由是沒有優先級的,當項目比較大、或有多個區域、或多個Web項目、或采用插件式框架開發時,我們的路由注冊很可能 不是寫在一個文件中的,而是分散在很多不同項目的文件中,這樣一來,路由的優先級的問題就突顯出來了。

比如: App_Start/RouteConfig.cs中

routes.MapRoute(     name: "Default",     url: "{controller}/{action}/{id}",     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );  Areas/Admin/AdminAreaRegistration.cs中  context.MapRoute(     name: "Login",        url: "login",     defaults: new { area = "Admin", controller = "Account", action = "Login", id = UrlParameter.Optional },     namespaces: new string[] { "Wenku.Admin.Controllers" } );

假如是先注冊上面那個通用的default路由,再注冊這個login的路由,那么無論怎么樣,都會先匹配***個滿足條件的路由,也就是第兩個路由注冊是無效的。
造成這個問題的原因就是這兩個路由注冊的順序問題,而Asp.Net MVC及WebApi中注冊路由都沒有優先級這個概念,所以今天我們就是要自己實現這個想法,在注冊路由時加入一個優先級的概念。

二、解決思路

1、先分析路由注冊的入口,比如我們新建一個mvc4.0的項目

public class MvcApplication : System.Web.HttpApplication {     protected void Application_Start()     {         AreaRegistration.RegisterAllAreas();          WebApiConfig.Register(GlobalConfiguration.Configuration);         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);         RouteConfig.RegisterRoutes(RouteTable.Routes);     } }

Mvc路由的注冊入口有兩個:
a. AreaRegistration.RegisterAllAreas();                            注冊區域路由
b. RouteConfig.RegisterRoutes(RouteTable.Routes);          注冊項目路由

WebApi路由注冊入口有一個:
WebApiConfig.Register(GlobalConfiguration.Configuration);  注冊WebApi路由

2、注冊路由的處理類分析

AreaRegistrationContext
RouteCollection
HttpRouteCollection

注冊路由時主要是由這三個類來注冊處理路由的。

3、路由優先級方案

a、更改路由的注冊入口
b、自定義一個路由的結構類RoutePriority及HttpRoutePriority,這兩個類下面都有Priority這個屬性
c、自定一個RegistrationContext來注冊路由,注冊的對象為上述自定義路由。
d、所有的路由注冊完成之后再按優先順序添加到RouteCollection及HttpRouteCollection中實際生效。

三、具體實現

1、路由定義

public class RoutePriority : Route {     public string Name { get; set; }     public int Priority { get; set; }      public RoutePriority(string url, IRouteHandler routeHandler)         : base(url,routeHandler)     {      } }  public class HttpRoutePriority {     public string Name { get; set; }     public int Priority { get; set; }     public string RouteTemplate{get;set;}     public object Defaults{get;set;}     public object Constraints{get;set;}     public HttpMessageHandler Handler{get;set;} }

2、定義路由注冊的接口

public interface IRouteRegister {     void Register(RegistrationContext context); }

3、定義路由注冊上下文類

public class RegistrationContext {     #region mvc     public List<RoutePriority> Routes = new List<RoutePriority>();      public RoutePriority MapRoute(string name, string url,int priority=0)     {         return MapRoute(name, url, (object)null /* defaults */, priority);     }      public RoutePriority MapRoute(string name, string url, object defaults, int priority = 0)     {         return MapRoute(name, url, defaults, (object)null /* constraints */, priority);     }      public RoutePriority MapRoute(string name, string url, object defaults, object constraints, int priority = 0)     {         return MapRoute(name, url, defaults, constraints, null /* namespaces */, priority);     }      public RoutePriority MapRoute(string name, string url, string[] namespaces, int priority = 0)     {         return MapRoute(name, url, (object)null /* defaults */, namespaces, priority);     }      public RoutePriority MapRoute(string name, string url, object defaults, string[] namespaces,int priority=0)     {         return MapRoute(name, url, defaults, null /* constraints */, namespaces, priority);     }      public RoutePriority MapRoute(string name, string url, object defaults, object constraints, string[] namespaces, int priority = 0)     {         var route = MapPriorityRoute(name, url, defaults, constraints, namespaces, priority);         var areaName = GetAreaName(defaults);         route.DataTokens["area"] = areaName;          // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up         // controllers belonging to other areas         bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);         route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;          return route;     }      private static string GetAreaName(object defaults)     {         if (defaults != null)         {             var property = defaults.GetType().GetProperty("area");             if (property != null)                 return (string)property.GetValue(defaults, null);         }          return null;     }      private RoutePriority MapPriorityRoute(string name, string url, object defaults, object constraints, string[] namespaces,int priority)     {         if (url == null)         {             throw new ArgumentNullException("url");         }          var route = new RoutePriority(url, new MvcRouteHandler())         {             Name = name,             Priority = priority,             Defaults = CreateRouteValueDictionary(defaults),             Constraints = CreateRouteValueDictionary(constraints),             DataTokens = new RouteValueDictionary()         };          if ((namespaces != null) && (namespaces.Length > 0))         {             route.DataTokens["Namespaces"] = namespaces;         }          Routes.Add(route);         return route;     }      private static RouteValueDictionary CreateRouteValueDictionary(object values)     {         var dictionary = values as IDictionary<string, object>;         if (dictionary != null)         {             return new RouteValueDictionary(dictionary);         }          return new RouteValueDictionary(values);     }     #endregion      #region http     public List<HttpRoutePriority> HttpRoutes = new List<HttpRoutePriority>();      public HttpRoutePriority MapHttpRoute(string name, string routeTemplate, int priority = 0)     {         return MapHttpRoute(name, routeTemplate, defaults: null, constraints: null, handler: null, priority: priority);     }      public HttpRoutePriority MapHttpRoute(string name, string routeTemplate, object defaults, int priority = 0)     {         return MapHttpRoute(name, routeTemplate, defaults, constraints: null, handler: null, priority: priority);     }      public HttpRoutePriority MapHttpRoute(string name, string routeTemplate, object defaults, object constraints, int priority = 0)     {         return MapHttpRoute(name, routeTemplate, defaults, constraints, handler: null, priority: priority);     }      public HttpRoutePriority MapHttpRoute(string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler, int priority = 0)     {         var httpRoute = new HttpRoutePriority();         httpRoute.Name = name;         httpRoute.RouteTemplate = routeTemplate;         httpRoute.Defaults = defaults;         httpRoute.Constraints = constraints;         httpRoute.Handler = handler;         httpRoute.Priority = priority;         HttpRoutes.Add(httpRoute);          return httpRoute;     }     #endregion }

4、把路由注冊處理方法添加到Configuration類中

public static Configuration RegisterRoutePriority(this Configuration config) {     var typesSoFar = new List<Type>();     var assemblies = GetReferencedAssemblies();     foreach (Assembly assembly in assemblies)     {         var types = assembly.GetTypes().Where(t => typeof(IRouteRegister).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);         typesSoFar.AddRange(types);     }      var context = new RegistrationContext();     foreach (var type in typesSoFar)     {         var obj = (IRouteRegister)Activator.CreateInstance(type);         obj.Register(context);     }      foreach (var route in context.HttpRoutes.OrderByDescending(x => x.Priority))         GlobalConfiguration.Configuration.Routes.MapHttpRoute(route.Name, route.RouteTemplate, route.Defaults, route.Constraints, route.Handler);      foreach (var route in context.Routes.OrderByDescending(x => x.Priority))         RouteTable.Routes.Add(route.Name, route);      return config; }  private static IEnumerable<Assembly> GetReferencedAssemblies() {     var assemblies = BuildManager.GetReferencedAssemblies();     foreach (Assembly assembly in assemblies)         yield return assembly; }

這樣一來就大功告成,使用時只需要在Global.asax.cs文件中修改原注冊入口為

public class MvcApplication : System.Web.HttpApplication {     protected void Application_Start()     {         WebApiConfig.Register(GlobalConfiguration.Configuration);         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);         RouteConfig.RegisterRoutes(RouteTable.Routes);          Configuration.Instance()             .RegisterComponents()             .RegisterRoutePriority(); //注冊自定義路由     } }

在每個項目中使用只需要要繼承自定義路由注冊接口IRouteRegister,例如:

public class Registration : IRouteRegister {     public void Register(RegistrationContext context)     {        //注冊后端管理登錄路由         context.MapRoute(           name: "Admin_Login",           url: "Admin/login",           defaults: new { area = "Admin", controller = "Account", action = "Login", id = UrlParameter.Optional },           namespaces: new string[] { "Wenku.Admin.Controllers" },           priority: 11       );         //注冊后端管理頁面默認路由         context.MapRoute(             name: "Admin_default",             url: "Admin/{controller}/{action}/{id}",             defaults: new { area = "Admin", controller = "Home", action = "Index", id = UrlParameter.Optional },             namespaces: new string[] { "Wenku.Admin.Controllers" },             priority: 10         );         //注冊手機訪問WebApi路由         context.MapHttpRoute(             name: "Mobile_Api",             routeTemplate: "api/mobile/{controller}/{action}/{id}",             defaults: new             {                 area = "mobile",                 action = RouteParameter.Optional,                 id = RouteParameter.Optional,                 namespaceName = new string[] { "Wenku.Mobile.Http" }             },             constraints: new { action = new StartWithConstraint() },             priority: 0         );     } }

“怎么給ASP.NET MVC及WebApi添加路由優先級”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安阳县| 拉萨市| 哈尔滨市| 盐源县| 武鸣县| 张家界市| 杭州市| 五大连池市| 吴江市| 包头市| 大新县| 陇西县| 桐城市| 随州市| 洛隆县| 香格里拉县| 南开区| 建始县| 双牌县| 大渡口区| 商洛市| 西畴县| 南部县| 梓潼县| 兴山县| 仙桃市| 兰西县| 合作市| 苍溪县| 通榆县| 象山县| 景洪市| 乌拉特中旗| 灵石县| 美姑县| 康平县| 稻城县| 阿克陶县| 中牟县| 秀山| 嘉荫县|