一、為什麼需要路由優先順序
大家都知道我們在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中實際生效。