- Modern Web Development with ASP.NET Core 3
- Ricardo Peres
- 995字
- 2021-06-18 18:35:59
Using routing attributes
An alternative to adding routes to a routing table is using routing attributes. Routing attributes existed before ASP.NET Core and were even around in ASP.NET MVC and Web API. If we want to have routing attributes automatically recognized by ASP.NET Core, we need to do this:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
In the following sections, we will learn about a few routing attributes and see how to apply them.
Let's see how we can define routes with attributes.
Defining routes
These attributes are used to define routes and can be composed together; if we add a routing attribute to a class and another to one of its methods, the actual route will result from both of them.
The most obvious use of routing attributes would be to decorate an action method, as follows:
[Route("Home/Index")]
public IActionResult Index() { ... }
If, for example, you have many actions in the same controller and you wish to map them all using the same prefix (Home), you can do the following:
[Route("Home")]
public class HomeController
{
[Route("Index")]
public IActionResult Index() { ... }
[Route("About")]
public IActionResult About() { ... }
}
Routes are additive, which means if you specify a route in a controller and then on an action method, you will get both, as in Home/Index or Home/About.
As you can see, the route parameter in the HomeController class matches the conventional name for the controller (Home). Because of this, we can also use the [controller] special token:
[Route("[controller]")]
public class HomeController { ... }
For an API controller, we can use this:
[Route("api/[controller]")]
public class ServicesController { ... }
In addition, each of the actions is mapped with a name that exactly matches the method's name. Likewise, we can use [action]:
[Route("[action]")]
public IActionResult Index() { ... }
[Route("[action]")]
public IActionResult About() { ... }
Multiple route attributes can be passed, so that the action method will respond to different requests:
[Route("[action]")]
[Route("")]
[Route("Default")]
public IActionResult Index() { ... }
The Index method will be callable by any one of the following requests:
/Home
/Home/Index
/Home/Default
Notice that the Home part comes from the route attribute applied at the class level. If, on the other hand, you specify a slash in the template, you make the template absolute; this template will look as follows:
[Route("Default/Index")]
public IActionResult Index() { ... }
This can only be accessed as follows:
/Default/Index
If you want to take the controller into consideration, you should either name it explicitly in the template or use the [controller] special token:
[Route("[controller]/Default/Index")]
public IActionResult Index() { ... }
This will be accessible as follows:
/Home/Default/Index
Default routes
With routing attributes, you can specify the default controller by applying RouteAttribute with a blank template:
[Route("")]
public class HomeController { ... }
The default action in a controller will also be the one with an empty template, as follows:
[Route("")]
public IActionResult Index() { ... }
If there is no method with an empty route template, ASP.NET Core will try to find one with a name matching the current HTTP method.
Constraining routes
You can also specify route constraints, and the syntax is identical to what we've seen before:
[Route("Calculate({a:int},{b:int})")]
public IActionResult Calculate(int a, int b) { ... }
Defining areas
You can define routes that include areas too, by applying AreaAttribute to a controller:
[Area("Products")]
[Route("[controller]")
public class ReportingController { ... }
Similar to [controller] and [action], there is also the special [area]token that you can use in your templates to indicate the current area, as inferred from the filesystem:
[Route("[area]/Default")]
public IActionResult Index() { ... }
Specifying action names
You can specify an action name for a controller method, through ActionNameAttribute, as follows:
[ActionName("Default")]
public IActionResult Index() { ... }
You can also do this through any one of the HTTP verb selection attributes (HttpGetAttribute, HttpPostAttribute, HttpPutAttribute, HttpOptionsAttribute, HttpPatchAttribute, HttpDeleteAttribute or HttpHeadAttribute):
[HttpGet(Name = "Default")]
public IActionResult Index() { ... }
Defining non-actions
If you want to prevent a public method in a controller class from being used as an action, you can decorate it with NonActionAttribute:
[NonAction]
public IActionResult Process() { ... }
Restricting routes
When we talked about route constraints, we saw that we can restrict an action method so that it is only callable if one or more the following conditions are met:
- It matches a given HTTP verb (ActionVerbsAttribute, Http*Attribute).
- It is called using HTTPS (RequireHttpsAttribute).
- It is called with a given content type (ConsumesAttribute).
We won't go into this in any further detail, as this has been explained before.
Setting route values
It is possible to supply arbitrary route values in an action method. This is the purpose of the RouteValueAttributeabstract class. You need to inherit from it:
public class CustomRouteValueAttribute : RouteValueAttribute
{
public CustomRouteValueAttribute(string value) : base("custom", value) { }
}
Then, apply and use it as follows:
[CustomRouteValue("foo")]
public IActionResult Index()
{
var foo = this.ControllerContext.RouteData.Values["foo"];
return this.View();
}
As you can see, quite a lot can be achieved through attributes. That also includes error handling; let's see more about that now.
- LabVIEW入門與實戰開發100例
- Visual Basic程序開發(學習筆記)
- BeagleBone Media Center
- 人臉識別原理及算法:動態人臉識別系統研究
- JS全書:JavaScript Web前端開發指南
- QGIS:Becoming a GIS Power User
- 深入淺出PostgreSQL
- UML 基礎與 Rose 建模案例(第3版)
- 青少年信息學競賽
- Go語言精進之路:從新手到高手的編程思想、方法和技巧(1)
- 軟件測試實用教程
- Learning Material Design
- Arduino計算機視覺編程
- Learning Jakarta Struts 1.2: a concise and practical tutorial
- 大學計算機基礎實訓教程