Explain how to use the Route feature in ASP. NET Core

  • 2021-11-24 01:18:12
  • OfStack

The Route middleware in ASP. NET Core is responsible for matching request to their respective Route handlers, and Route is divided into two types: convention-based and basic feature patterns.

Route based on convention pattern adopts centralized mode, while feature-based mode allows you to define it separately on Action or Controller. Which one can be adopted based on your own application scenario, this article will discuss how to use feature-based mode.

Create an Controller class

Create an DefaultController class and add the following code.


 public class DefaultController : Controller
 {
  [Route("")]
  [Route("Default")]
  [Route("Default/Index")]
  public ActionResult Index()
  {
   return new EmptyResult();
  }
  [Route("Default/GetRecordsById/{id}")]
  public ActionResult GetRecordsById(int id)
  {
   string str = string.Format
   ("The id passed as parameter is: {0}", id);
   return Ok(str);
  }
 }

The Controller level defines Route features

The Route feature is available at the Controller and Action levels, and it is worth noting that all Action under Controller are governed by this Route if the former should be reached.

If you look closely at the above DefaultController class code, you will find that the Route paths of the two Action methods have Default prefixes, which is not elegant. The optimization method is to extract Default from Route path to Controller level. The code is as follows:


[Route("Default")] 
public class DefaultController : Controller
{
 [Route("")]
 [Route("Index")]
 public ActionResult Index()
 {
  return new EmptyResult();
 }
 [HttpGet]
 [Route("GetRecordsById/{id}")]
 public ActionResult GetRecordsById(int id)
 {
  string str = string.Format("The id passed as parameter is: {0}", id);
  return Ok(str);
 }
}

It can be seen that when Controller and Action levels are marked by Route, the Route engine in Asp. Net Core will automatically splice them together. Of course, the simpler and ruder way is to use RoutePrefix features on Controller, as shown in the following code:


[RoutePrefix("services")]
public class HomeController : Controller
{
 //Action methods
}

The Action level defines Route characteristics

Referring to the DefaultController class just now, I defined three Route properties on top of the Index method, which means that the following three Route can access the Index () method, as shown in the following code:

http://localhost:11277
http://localhost:11277/home
http://localhost:11277/home/index

Often in a convention-based Route, its Route template has one convention on parameters, such as the following code:


   app.UseEndpoints(endpoints =>
   {
    endpoints.MapControllerRoute(
     name: "default",
     pattern: "{controller=Home}/{action=Index}/{id?}");
   });

Similarly, Route based on feature mode can also use parameter mode, such as DefaultController. GetRecordsById before the article. It is worth noting that {id} in the template means that any parameter can be accepted, such as string, int, etc., which can also be implemented if you want to limit it to int.

Using Route constraints

The Route constraint is a firewall before Controller, which will kick out some non-standard Action requests. For example, if you require that the parameters received by an Action must be int, the syntax format 1 defined in the Route template must be {parameter: constraint}, as shown in the following code:


[Route("Default/GetRecordsById/{id:int}")]
public ActionResult GetRecordsById(int id)
{
 string str = string.Format("The id passed as parameter is: {0}", id);
 return Ok(str);
}

Using optional parameters in Route

You can also specify an optional parameter on Route Template, meaning that this parameter can be passed or not, in the following format:


[Route("Sales/GetSalesByRegionId/{id?}")]

One important point is that when you use the Route feature, the name of Controller or Action is no longer important because the Route processing engine no longer uses it as a reference option. The following code snippet shows how to change the Route template format on the Action method.


[Route("Home/GetRecordsById/{id:int}")]
public ActionResult GetRecordsById(int id)
{
 string str = string.Format("The id passed as parameter is: {0}", id);
 return Ok(str);
}

Next, you can directly access the GetRecordsById method using the following address.

http://localhost:11277/home/GetRecordsById/1

Use multiple constraints on parameters in Action

In the real scene, you not only require id to be an integer, but also require it to have a definite meaning, for example, the minimum value is 1. How to realize this requirement with multiple constraints? Look at the code below.


[Route("Default/GetRecordsById/{id:int:min(1)}")]
public ActionResult GetRecordsById(int id)
{
 string str = string.Format("The id passed as parameter is: {0}", id);
 return Ok(str);
}

Commonly used Route constraints

int is qualified to the int type max/min defines the maximum and minimum number of int minlength defines the minimum length of string regex-defined conforming regularity

Create a custom Route constraint

If the above constraints do not meet your requirements, you can deeply customize your scene by using the IRouteConstraint interface and implementing its Match method, as shown in the following code:


 public class CustomRouteConstraint : IRouteConstraint
 {
  public bool Match(HttpContext httpContext, IRouter route,
  string routeKey,
  RouteValueDictionary values, RouteDirection routeDirection)
  {
   throw new NotImplementedException();
  }
 }

Using token placeholders on Controller

The so-called token placeholder is a placeholder with one specific meaning, such as [action], [area] and [controller], which means to replace with your real Controller and Action, respectively. The following code shows how to use this pattern.


[Route("[controller]/[action]")]
public class HomeController : Controller
{
 private readonly ILogger<HomeController> _logger;
 public HomeController(ILogger<HomeController> logger)
 {
  _logger = logger;
 }
 public IActionResult Index()
 {
  return View();
 }
 //Other action methods
}

On the whole, Route based on features gives you more control rights, and flexible Route Template configuration realizes the decoupling of Controller and Action. Of course, this is not to say that Route based on conventions is not good. After all, people are Global level, and the two are more mixed in real scenes.

Translation link: https://www.infoworld.com/article/3569369/how-to-use-attribute-routing-in-aspnet-core.html


Related articles: