[Asp.net MVC] Asp.net MVC5 series -- Routing features
ASP. net mvc 5 supports a new routing protocol called routing feature. As the name suggests, the routing feature uses features to define the path. The routing feature gives you more control over the Web application URI. Of course, MVC5 also supports the previously defined routing method. You can use both methods to define routing in a project. For example, an e-commerce website may have the following routing rules: {productId: int}/{productTitle} Mapped to ProductsController. show (int id) {username} Mapped to ProfilesController. show (string username) {username}/catalogs/{catalogId: int}/{catalogTitle} Mapped to CatalogsController. show (string username, int catalogId) Previous ASP.. net mvc version, which is set in routeconfig. cs file, and points out the actual controller Action method, such as: 1 routes. mapRoute (2 name: "ProductPage", 3 url: "{productId }/{ ProductTitle} ", 4 defaults: new {controller =" Products ", action =" Show "}, 5 constraints: new {productId =" \ d + "} 6 ); when the routing definition and Action method are declared in the same source file rather than in the external configuration class, it can easily process the URI ing between the URI and the Action. The previous path definition uses the following features to achieve the goal: 1 [Route ("{productId: int}/{productTitle}")] 2 public ActionResult Show (int productId ){...} to use the routing feature, you must first enable Attribute routing. You can call the MapMvcAttributeRoutes method to enable Attribute routing: Copy code 1 public class RouteConfig2 {3 public static void RegisterRoutes (RouteCollection routes) 4 {5 routes. ignoreRoute ("{resource }. axd/{* pathInfo} "); 6 7 routes. mapMvcAttributeRoutes (); 8} 9} the copy code can also be used with the conventional routing settings. Copy code 1 public static void RegisterRoutes (RouteCollection routes) 2 {3 routes. ignoreRoute ("{resource }. axd/{* pathInfo} "); 4 5 routes. mapMvcAttributeRoutes (); 6 7 routes. mapRoute (8 name: "Default", 9 url: "{controller}/{action}/{id}", 10 defaults: new {controller = "Home ", action = "Index", id = UrlParameter. optional} 11); 12} copy the Optional URI parameter and the default value of the parameter in the Code by adding "?" Mark a parameter as an optional parameter, or set the default value (parameter = value) for the form parameter ). Copy code 1 public class BooksController: Controller 2 {3 // eg:/books 4 // eg:/books/1430210079 5 [Route ("books/{isbn ?} ")] 6 public ActionResult View (string isbn) 7 {8 if (! String. isNullOrEmpty (isbn) 9 {10 return View ("OneBook", GetBook (isbn); 11} 12 return View ("AllBooks", GetBooks ()); 13} 14 15 // eg:/books/lang16 // eg:/books/lang/en17 // eg: /books/lang/he18 [Route ("books/lang/{lang = en}")] 19 public ActionResult ViewByLanguage (string lang) 20 {21 return View ("OneBook ", getBooksByLanguage (lang); 22} 23} copy the Code. In the preceding example,/books and/books/1430210079 are routed to the View method. The former returns the list information of all books, and the latter Will return information about the specific book. /Books/lang and/books/lang/en will adopt the same method. The route prefix is in the same Controller. The route starts with the same prefix. For example, copy code 1 public class ReviewsController: Controller 2 {3 // eg: /reviews 4 [Route ("reviews")] 5 public ActionResult Index (){...} 6 // eg:/reviews/5 7 [Route ("reviews/{reviewId}")] 8 public ActionResult Show (int reviewId ){...} 9 // eg:/reviews/5/edit10 [Route ("reviews/{reviewId}/edit")] 11 public ActionResult Edit (int reviewId ){...} 12} You can use [routeprefix] Features the entire Controller sets a common prefix: Copy code 1 [RoutePrefix ("reviews")] 2 public class ReviewsController: Controller 3 {4 // eg. :/reviews 5 [Route] 6 public ActionResult Index (){...} 7 // eg. :/reviews/5 8 [Route ("{reviewId}")] 9 public ActionResult Show (int reviewId ){...} 10 // eg. :/reviews/5/edit11 [Route ("{reviewId}/edit")] 12 public ActionResult Edit (int reviewId ){...} 13} copy the Code. If you need to define different route prefixes, you can use the Tilde in method features. ~ Overwrite the original prefix, for example: Copy code 1 [RoutePrefix ("reviews")] 2 public class ReviewsController: Controller3 {4 // eg.:/spotlight-review5 [Route ("~ /Spotlight-review ")] 6 public ActionResult ShowSpotlight (){...} 7 8... 9} copy the default code route. You can also use the [path] feature at the Controller level to take the Action method as a parameter. This route will be applied to all Action methods in the Controller. Unless the Action method uses a specific [Route] feature, the Controller-level default route will be used. Copy code 1 [RoutePrefix ("promotions")] 2 [Route ("{action = index}")] 3 public class ReviewsController: Controller 4 {5 // eg. :/promotions 6 public ActionResult Index (){...} 7 8 // eg. :/promotions/archive 9 public ActionResult Archive (){...} 10 11 // eg. :/promotions/new12 public ActionResult New (){...} 13 14 // eg. :/promotions/edit/515 [Route ("edit/{promoId: int}")] 16 public ActionResult Edit (Int promoId) {...} 17} the copied Code shows that the routing feature priority of the Action method is higher than that of the controller routing feature. The routing constraint allows you to restrict how the parameters in the routing template match. The common syntax is {parameter: constraint}. For example, copy code 1 // eg: /users/52 [Route ("users/{id: int}"] 3 public ActionResult GetUserById (int id ){...} 4 5 // eg: users/ken6 [Route ("users/{name}"] 7 public ActionResult GetUserByName (string name ){...} copy the Code. If the id is of the int type, the first route is selected. Otherwise, the second route is selected. The following table lists the supported constraints: note that some of the constraints with min can contain parameters. You can also apply multiple constraints on a single parameter. Multiple constraints are separated by semicolons (;), for example, 1 // eg: /users/52 // but not/users/10000000000 because it is larger than int. maxValue, 3 // and not/users/0 because of the min (1) constraint.4 [Route ("users/{id: int: min (1)}")] 5 public ActionResult GetUserById (int id ){...} question mark "? "You can specify Optional parameters in the inline constraint, such as: 1 // eg:/greetings/bye2 // and/greetings because of the Optional modifier, 3 // but not/greetings/see-you-tomorrow because of the maxlength (3) constraint.4 [Route ("greetings/{message: maxlength (3 )?} ")] 5 public ActionResult Greet (string message ){...} custom route constraints can be customized by implementing the IRouteConstraint interface. For example, to define a parameter validity constraint, copy code 1 public class ValuesConstraint: IRouteConstraint 2 {3 private readonly string [] validOptions; 4 public ValuesConstraint (string options) 5 {6 validOptions = options. split ('|'); 7} 8 9 public bool Match (HttpContextBase httpContext, Route route, string parameterName, RouteValueDicti Onary values, RouteDirection routeDirection) 10 {11 object value; 12 if (values. TryGetValue (parameterName, out value) & value! = Null) 13 {14 return validOptions. contains (value. toString (), StringComparer. ordinalIgnoreCase); 15} 16 return false; 17} 18} copy the code and register the custom constraints: copy code 1 public class RouteConfig 2 {3 public static void RegisterRoutes (RouteCollection routes) 4 {5 routes. ignoreRoute ("{resource }. axd/{* pathInfo} "); 6 7 var constraintsResolver = new DefaultInlineConstraintResolver (); 8 9 constraintsResolver. constraintMap. Add ("values", typeof (ValuesConstraint); 10 11 routes. mapMvcAttributeRoutes (constraintsResolver); 12} 13} now, you can use the custom constraint in your route to copy code 1 public class TemperatureController: controller2 {3 // eg: temp/celsius and/temp/fahrenheit but not/temp/kelvin4 [Route ("temp/{scale: values (celsius | fahrenheit)}")] 5 public ActionResult Show (string scale) 6 {7 return Content ("scale is" + scale); 8} 9} copy the code route name you can Specify a name for a route to generate a url. Example: 1 [Route ("menu", Name = "mainmenu")] 2 public ActionResult MainMenu (){...} you can use Url. routeUrl to generate the corresponding URL 1 <a href = "@ Url. routeUrl ("mainmenu") "> Main menu </a> Area. You can use the [RouteArea] feature to specify a region where a controller belongs, you can safely remove the AreaRegistration class from the region: Copy code 1 [RouteArea ("Admin")] 2 [RoutePrefix ("menu")] 3 [Route ("{action}")] 4 public class MenuController: Controller 5 {6 // eg:/admin/menu/login 7 public Actio NResult Login (){...} 8 9 // eg:/admin/menu/show-options10 [Route ("show-options")] 11 public ActionResult Options (){...} 12 13 // eg:/stats14 [Route ("~ /Stats ")] 15 public ActionResult Stats (){...} 16} copy the code to use this controller. The following link will generate the following url: "/Admin/menu/show-options" Url. action ("Options", "Menu", new {Area = "Admin"}) You can also use the AreaPrefix parameter to create a custom region prefix. For example: [RouteArea ("BackOffice", AreaPrefix = "back-office) if you use the traditional routing region method, you must register the region before configuring the MVC routing feature. The reason is simple, the route registration sequence must start with the most accurate matching rule and then follow the common matching rule. The last is the Fuzzy Matching Rule, which avoids premature matching during route matching. Fuzzy Rules, but relatively precise matching does not play any role. The following example shows how to copy code 1 public static void RegisterRoutes (RouteCollection routes) 2 {3 routes. ignoreRoute ("{resource }. axd/{* pathInfo} "); 4 5 routes. mapMvcAttributeRoutes (); 6 7 AreaRegistration. registerAllAreas (); 8 9 routes. mapRoute (10 name: "Default", 11 url: "{controller}/{action}/{id}", 12 defaults: new {controller = "Home ", action = "Index", id = UrlParameter. optional} 13); 14}