乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      給Asp.Net MVC及WebApi添加路由優(yōu)先級

       WindySky 2017-10-10

      一、為什么需要路由優(yōu)先級

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

      比如: 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" } );

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

      二、解決思路

      1、先分析路由注冊的入口,比如我們新建一個(gè)mvc4.0的項(xiàng)目

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

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

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

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

          注冊路由時(shí)主要是由這三個(gè)類來注冊處理路由的。

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

      三、具體實(shí)現(xiàn)

      1、路由定義

      復(fù)制代碼
      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;}
      }
      復(fù)制代碼

      2、定義路由注冊的接口

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

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

      復(fù)制代碼
      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
      }
      復(fù)制代碼

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

      復(fù)制代碼
      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;
      }
      復(fù)制代碼

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

      復(fù)制代碼
      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(); //注冊自定義路由
          }
      }
      復(fù)制代碼

      在每個(gè)項(xiàng)目中使用只需要要繼承自定義路由注冊接口IRouteRegister,例如:

      復(fù)制代碼
      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
            );
      
             //注冊后端管理頁面默認(rèn)路由
              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
              );
      
             //注冊手機(jī)訪問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
              );
          }
      }
      復(fù)制代碼

      四、總結(jié)

          這是一個(gè)對Asp.Net Mvc的一個(gè)很小的功能拓展,小項(xiàng)目可能不太需要這個(gè)功能,但有時(shí)候項(xiàng)目大了注冊的路由不生效時(shí)你應(yīng)該要想到有可能是因?yàn)槁酚身樞虻脑?,這時(shí)這個(gè)路由優(yōu)先級的功能有可能就會給你帶來便利??傊蚕斫o有需要的朋友們參考。

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多