Add route priority for ASP.net mvc and webapi-practical tips

Source: Internet
Author: User

First, why the need for routing priority

We all know that we have no priority in registering routes in the ASP.net MVC project or Webapi project, when the project is larger, has multiple zones, or multiple Web projects, or is developed with a plug-in framework, our route registration is probably not written in one file, Instead, they are scattered across a number of different projects, so that the priority of the routing problem 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} 
); 
 
Areas/admin/adminarearegistration.cs in the context 
 
. Maproute ( 
  name: "Login",  
  URL: "Login", 
  defaults:new {area = "Admin"), Controller = "Account", action = "Logi n ", id = urlparameter.optional}, 
  namespaces:new string[] {" Wenku.Admin.Controllers "} 
); 

If you register the above generic default route and then register the login route, you will first match the first route that satisfies the condition, that is, the two route registration is invalid.
This problem is caused by the sequence of these two routing registrations, and there is no priority to registering routes in asp.net mvc and webapi, so today we are going to implement this idea ourselves by adding a priority concept when registering a route.

Second, the solution to the idea

1, first analysis of the route registration portal, such as 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 the MVC route:
A. Arearegistration.registerallareas (); Registering area routes
B. routeconfig.registerroutes (routetable.routes); registering project Routes

There is a WEBAPI route registration entry:
Webapiconfig.register (globalconfiguration.configuration); Registering WEBAPI Routing

2, the Registration route processing class analysis

AreaRegistrationContext
RouteCollection
Httproutecollection

When you register a route, these three classes are primarily registered to handle the route.

3. Route priority scheme

A, change the registration entry for the route
b, customize the structure class routepriority and httproutepriority of a route, these two classes have priority this property
C, custom a registrationcontext to register the route, the registered object for the above custom route.
D, after all the routing registrations are completed and then added to RouteCollection and httproutecollection in the order of precedence, it actually takes effect.

Third, the concrete realization

1. Routing 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 of Route registration

Public interface Irouteregister 
{ 
  void Register (Registrationcontext context); 

3. Define route Registration Context class

public class Registrationcontext {#region mvc list<routepriority> Routes = new list<routepriority 
 
  > ();  Public routepriority Maproute (string name, String Url,int priority=0) {return maproute (name, URL, (object) NULL/* 
  Defaults * *, priority); 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); Routepriority Maproute (string name, string URL, string[] namespaces, int priority = 0) {return mapr 
  Oute (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); Routepriority Maproute (string name, string URL, object defaults, object constraints, string[] namespaces, in 
    T 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 Bel Onging to the 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 = Def Aults. 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[] Names 
    Paces,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 to New RoutevAluedictionary (values); #endregion #region http public list 

4, the route registration processing method to add to the configuration class

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); 
  The var context = new Registrationcontext (); 
    foreach (var type in Typessofar) {var obj = (irouteregister) activator.createinstance (type); Obj. 
  Register (context); foreach (var route in the context.) Httproutes.orderbydescending (x => x.priority)) GlobalConfiguration.Configuration.Routes.MapHttpRoute (route. Name, route. Routetemplate, route. Defaults, route. Constraints, route. 
 
  Handler); foreach (var route in the context.) Routes.orderbydescending (x => x.priority)) RouteTable.Routes.Add (route. 
 
  Name, route); 
return config; } private static IENUMERABLE&LT 
  Assembly> getreferencedassemblies () {var assemblies = buildmanager.getreferencedassemblies (); 
foreach (Assembly Assembly in assemblies) yield return Assembly; This is the end of the work, only to modify the original registration entry in the Global.asax.cs file as public class MvcApplication:System.Web.HttpApplication {protected VO 
    ID Application_Start () {webapiconfig.register (globalconfiguration.configuration); 
    Filterconfig.registerglobalfilters (globalfilters.filters); 
 
    Routeconfig.registerroutes (routetable.routes); Configuration.instance (). Registercomponents (). Registerroutepriority ();  Registering custom Routes}} Use only the custom route registration interface Irouteregister that you want to inherit in each project, for example: public class Registration:irouteregister {public void Register (Registrationcontext context) {//Register back-end Admin 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 back-end Admin page Default routing context. Maproute (Name: "Admin_default", url: "Admin/{controller}/{action}/{id}", defaults:new {area = "Adm In ", Controller =" Home ", action =" Index ", id = urlparameter.optional}, namespaces:new string[] {" Wenku.admin.c 
 
    Ontrollers "}, Priority:10); Register Mobile Access Webapi routing context. Maphttproute (Name: "Mobile_api", Routetemplate: "Api/mobile/{controller}/{action}/{id}", Defaults:n 
        ew {area = "mobile", action = routeparameter.optional, id = routeparameter.optional, NamespaceName = new string[] {"Wenku.Mobile.Http"}}, constraints:new {action = new startwithcons 
  Traint ()}, priority:0); 

 } 
}

Iv. Summary

When you encounter a large project registration route does not take effect you should think that there may be the reason for the routing order, the above is the entire content of this article, I hope that the study of everyone to inspire.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.