1. What is attribute routing? How do I enable attribute routing?
Microsoft introduced a new route in ASP. MVC5: Attribute routing, as the name implies, attribute routing is defined by attribute. Of course, MVC5 also supports the way in which routes were previously defined, and you can use these two methods to define routes in a single project.
In previous releases, we typically defined routes in the RouteConfig.cs file in the following ways:
Routes. MapRoute ( name: "Productpage", URL: "{productid}/{producttitle}", defaults:new {controller = "Products" , action = "Show"}, constraints:new {productId = "\\d+"});
In MVC5, we can put the route definition and Action together:
[Route ("{productid:int}/{producttitle}")]public actionresult Show (int productId) {...}
Of course, first you have to enable attribute routing, we can call the Mapmvcattributeroutes method to enable attribute routing:
public class routeconfig{public static void RegisterRoutes (RouteCollection routes) { routes. Ignoreroute ("{resource}.axd/{*pathinfo}"); Routes. Mapmvcattributeroutes (); }}
2. URL Optional parameters and default values
We can use the question mark "?" To mark an optional parameter, you can also set a default value for the parameter:
public class bookscontroller:controller{ //Match:/books //Match:/books/1430210079 //question mark indicates that ISBN is optional [Rout E ("Books/{isbn?}")] Public ActionResult View (string ISBN) { if (! String.IsNullOrEmpty (ISBN)) { return View ("Onebook", GetBook (ISBN)); } Return View ("Allbooks", Getbooks ()); } Matching:/books/lang //Match:/books/lang/en //Match:/books/lang/he //If the URL does not pass the lang parameter, the value of Lang is "en" [ Route ("books/lang/{lang=en}")] public actionresult viewbylanguage (string lang) { return View (" Onebook ", Getbooksbylanguage (Lang));} }
3. Route Prefix
Sometimes in the same Controller, all Action-matching URLs have the same prefix, as follows:
public class reviewscontroller:controller{ //match:/reviews [Route ("reviews")] public ActionResult Index ( ) { ... } Match:/reviews/5 [Route ("Reviews/{reviewid}")] public actionresult Show (int reviewid) {...} Match:/reviews/5/edit [Route ("Reviews/{reviewid}/edit")] public actionresult edit (int reviewid) {...}}
We see that all the actions under Reviewscontroller are preceded by "reviews", where we can set the route prefix with [Routeprefix] on the Controller, with a common prefix for each action-matched URL "Reviews":
[Routeprefix ("Reviews")]public class reviewscontroller:controller{ //match:/reviews [Route] public ActionResult Index () {...} Match:/reviews/5 [Route ("{Reviewid}")] public actionresult Show (int reviewid) {...} Match:/reviews/5/edit [Route ("{reviewid}/edit")] public actionresult edit (int reviewid) {...}}
But what if an Action doesn't want the prefix? Of course there is a way, we can use the wave number "~" To remove it:
[Routeprefix ("Reviews")]public class reviewscontroller:controller{//match:/spotlight-review[route ("~/ Spotlight-review ")]public ActionResult showspotlight () {...} ...}
4. Default route
In addition to using [route] on the Action, we can also use the controller, when [route] is used on the controller, it defines a default routing rule that will work on all actions under the controller, Unless the [route] attribute is also applied on an Action, the [route] on the Controller is overwritten. Note, however, that the [Route] applied to the Controller must be prefixed with {action}, otherwise it will be thrown "Routedata must contain an item named ' Action ' with a value of a non-empty string." Error The [Route] applied on the action is not added, because {action} is the current action.
[Routeprefix ("promotions")] [Route ("{action=index}")]
The default route is defined above, and the default value for {action} is "index",//That is, when the URL does not contain {action}, the default call action is index. public class reviewscontroller:controller{ //Match:/promotions public ActionResult Index () {...} Match:/promotions/archive public ActionResult Archive () {...} Match:/promotions/new public actionresult new () {...} Match:/PROMOTIONS/EDIT/5 //This overrides the default routing rule //According to the default route, this should match:/promotions/editproduct?promoid=5 [Route (" Edit/{promoid:int} ")] public actionresult editproduct (int promoid) {...}}
5. Routing Constraints
Routing constraints allow you to specify the type and range of parameters, such as: {parameter: constraint}, for example:
Match:/users/5[route ("Users/{id:int}"]//here constrains the parameter "id" must be an integer type public actionresult getuserbyid (int id) {...}
The following is a list of supported routing constraints:
Alpha, must be uppercase and lowercase letters (a-z,a-z), such as: {X:alpha};
BOOL, must be a Boolean value, such as: {X:bool}
datetime, must be a datetime (time and date) type, such as: {x:datetime}
Decimal, which must be of type decimal, such as: {X:decimal}
Double, must be a 64bit floating-point number, such as: {x:double}
Float, must be a 32bit floating-point number, such as: {x:float}
GUID, must be GUID, for example: {x:guid}
int, must be a 32bit integer, such as: {X:int}
Length, the string must be of the specified value or within the specified range, such as: {X:length (6)} {x:length (1,20)}
Long, must be a 64bit integer, such as: {X:long}
Max, an integer less than or equal to the specified value, such as: {X:max (10)}
MaxLength, the string length is less than or equal to the specified value, such as: {X:maxlength (10)}
Min, an integer integer greater than or equal to the specified value, such as: {X:min (10)}
MinLength, the string length is greater than or equal to the specified value, such as: {X:minlength (10)}
Range, must be an integer within a given range, such as: {X:range (10,50)}
Regex, which must match a regular expression, such as: {x: (^\d{3}-\d{3}-\d{4}$)}
You can apply multiple constraints after a parameter, separating them with colons, as follows:
Match:/users/5//but does not match/users/10000000000 because the value of ID has exceeded int. maxvalue,//also does not match/users/0 because there is a min (1) constraint behind it, the value of ID must be greater than or equal to 1. [Route ("Users/{id:int:min (1)}")]public actionresult Getuserbyid (int id) {...}
It is important to note that the constraints are added to the optional parameters, for example:
Match:/greetings/bye//also matches/greetings because the message is an optional parameter,//but does not match/greetings/see-you-tomorrow because there is a maxlength (3) constraint. [Route ("Greetings/{message:maxlength (3)}")] Public ActionResult Greet (String message) {...}
6. Custom Routing constraints
We can customize the routing constraints by implementing the Irouteconstraint interface. The following example shows how to customize a route constraint:
public class valuesconstraint:irouteconstraint{ private readonly string[] validoptions; Public Valuesconstraint (String options) { validoptions = options. Split (' | '); } public bool Match (HttpContextBase HttpContext, Route route, string parametername, routevaluedictionary values, routedirection routedirection) { object value; if (values. TryGetValue (parametername, out value) && value! = null) { return validoptions.contains (value. ToString (), stringcomparer.ordinalignorecase); } return false; }}
The following code shows how to register a custom routing constraint
public class routeconfig{public static void RegisterRoutes (RouteCollection routes) { routes. Ignoreroute ("{resource}.axd/{*pathinfo}"); var constraintsresolver = new Defaultinlineconstraintresolver (); CONSTRAINTSRESOLVER.CONSTRAINTMAP.ADD ("Values", typeof (Valuesconstraint)); Routes. Mapmvcattributeroutes (Constraintsresolver); }}
Now we can use these custom routing constraints in our code:
public class temperaturecontroller:controller{ //matches Temp/celsius and/temp/fahrenheit but does not match/temp/kelvin [Route ("Temp/{scale:values (Celsius|fahrenheit)}")] Public ActionResult Show (string scale) { return Content (' scale is ' + scale);} }
7. Route Name
You can specify a name for the routing rule to facilitate the generation of the appropriate URL, for example:
[Route ("menu", Name = "MainMenu")]public ActionResult MainMenu () {...}
You can use Url.routeurl to generate the appropriate URL:
<a href= "@Url. ROUTEURL (" MainMenu ")" >main menu</a>
8. Area
The area concept of the ASP. NET MVC is very useful for organizing large web applications, and in attribute routing, of course, it is supported, as long as the use of [Routearea], you can take the Controller to a certain area, you can safely delete The Arearegistration class under area:
[Routearea ("Admin")] [Routeprefix ("menu")] [Route ("{action}")]public class menucontroller:controller{ //Match:/admin/menu/login public ActionResult Login () {...} Match:/admin/menu/show-options [Route ("Show-options")] public actionresult options () {...} Match:/stats [Route ("~/stats")] public ActionResult stats () {...}}
Now you can use the "Admin" area as in previous versions, the following code generates the URL "/admin/menu/show-options":
Url.action ("Options", "menu", new {area = "Admin"})//You can also set the area prefix via Areaprefix, for example: [Routearea ("BackOffice", Areaprefi x = "Back-office")]
If you use both the Attribute and Arearegistration classes to register an area, you should use Arearegistration to register the area between the registered Attribute route and the traditional route map for a simple reason. The order of the route registration must be from the most precise matching rule to the normal matching rule, and finally the fuzzy matching rule, which avoids the early matching of the fuzzy rule in the route matching, and the relative exact match does not have any effect. This is shown in the following example:
public static void RegisterRoutes (RouteCollection routes) { routes. Ignoreroute ("{resource}.axd/{*pathinfo}"); Routes. Mapmvcattributeroutes (); Arearegistration.registerallareas (); Routes. MapRoute ( name: "Default", URL: "{controller}/{action}/{id}", defaults:new {controller = "Home", actio n = "Index", id = urlparameter.optional} );
ASP. NET MVC5 new features: Attribute routing usage explained