Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to add routing priority to ASP.NET MVC and WebApi

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the knowledge of "how to add routing priority to ASP.NET MVC and WebApi". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

First, why routing priority is needed

As we all know, there is no priority for us to register routes in Asp.Net MVC projects or WebApi projects. When the project is relatively large, or there are multiple regions, or multiple Web projects, or using plug-in framework development, our route registration is probably not written in one file, but scattered in many different project files. In this way, the problem of routing priority is highlighted.

For example: in App_Start/RouteConfig.cs

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

If you first register the general default route above, and then register the login route, then no matter what, it will first match the first route that meets the criteria, that is, the second route registration is invalid.

The reason for this problem is the order of the registration of these two routes, and there is no concept of priority in registered routes in Asp.Net MVC and WebApi, so today we are going to implement this idea by adding a concept of priority when registering routes.

Second, the solution.

1. First analyze the entry of route registration, for example, we create a new mvc4.0 project.

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

There are two registered entries for Mvc routing:

A. AreaRegistration.RegisterAllAreas (); registered area routing

B. RouteConfig.RegisterRoutes (RouteTable.Routes); register project routing

There is one entry for WebApi routing registration:

WebApiConfig.Register (GlobalConfiguration.Configuration); register WebApi routing

2. Analysis of the processing class of registered routing.

AreaRegistrationContext

RouteCollection

HttpRouteCollection

When registering a route, it is mainly these three classes that register to handle the route.

3. Routing priority scheme

A. Change the registration entry of the route

B. Customize the structure classes RoutePriority and HttpRoutePriority of a route, both of which have the attribute Priority

C, customize a RegistrationContext to register the route, and the registered object is the above custom route.

D. After all routes are registered, they will be added to RouteCollection and HttpRouteCollection in order of priority.

III. Concrete realization

1. Route definition

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. Define the interface for route registration

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

3. Define the route registration context class

Public class RegistrationContext {# region mvc public List Routes = new List (); 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; if (dictionary! = null) {return new RouteValueDictionary (dictionary);} return new RouteValueDictionary (values);} # endregion # region http public List HttpRoutes = new List (); 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. Add the route registration processing method to the Configuration class

Public static Configuration RegisterRoutePriority (this Configuration config) {var typesSoFar = new List (); 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 GetReferencedAssemblies () {var assemblies = BuildManager.GetReferencedAssemblies () Foreach (Assembly assembly in assemblies) yield return assembly;} is done. You only need to modify the original registration entry in the Global.asax.cs file to 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 () / / register a custom route}} use in each project only need to inherit the custom route registration interface IRouteRegister For example: public class Registration: IRouteRegister {public void Register (RegistrationContext context) {/ / register backend management login routing 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) / / register the default route context.MapRoute of the backend management page (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) / / register for mobile phone access WebApi routing 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) This is the end of "how to add routing priority to ASP.NET MVC and WebApi". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report