[translation] ASP.NET Core 2.0 routing engine details

Time:2020-11-17

This paper introduces the ASP.NET 2. Details of the core are as follows:

problem

ASP.NET How does the routing engine of core 2.0 work?

answer

Create an MVC middleware and an empty service class


public void ConfigureServices(IServiceCollection services)

{

  services.AddMvc();

}

 

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

  app.UseMvc(routes =>

  {

    routes.MapRoute(

      name: "goto_one",

      template: "one",

      defaults: new { controller = "Home", action = "PageOne" });

 

    routes.MapRoute(

      name: "goto_two",

      template: "two/{id?}",

      defaults: new { controller = "Home", action = "PageTwo" });

 

    routes.MapRoute(

      name: "default",

      template: "{controller=Home}/{action=Index}/{id?}");

  });

} 

Create a controller, homecontroller, to demonstrate general routing:


public class HomeController : Controller

{

  public IActionResult Index()

  {

    return Content("Home/Index");

  }

 

  public IActionResult PageOne()

  {

    return Content("Home/One");

  }

 

  [HttpGet]

  public IActionResult PageTwo()

  {

    return Content("(GET) Home/Two");

  }

 

  [HttpPost]

  public IActionResult PageTwo(int id)

  {

    return Content($"(POST) Home/Two: {id}");

  }

} 

Create a controller, workcontroller, to demonstrate feature Routing:


[Route("work")]

public class WorkController : Controller

{

  public IActionResult Index()

  {

    return Content("Work/Index");

  }

 

  [Route("one")]

  public IActionResult PageOne()

  {

    return Content("Work/One");

  }

 

  [HttpGet("two")]

  public IActionResult PageTwo()

  {

    return Content("(GET) Work/Two");

  }

 

  [HttpPost("two/{id?}")]

  public IActionResult PageTwo(int id)

  {

    return Content($"(POST) Work/Two: {id}");

  }

} 

discuss

ASP.NET The core’s routing engine maps incoming requests to controllers and their methods. This is achieved by adding routing middleware to the request pipeline. Specifically, it uses iroutebuilder to map URL rules (templates) to a controller.

Routing template

Routing templates can use literals and tags (identifying route parameters). When matching a route, the literal matches the text in the URL exactly, and the tag is replaced.

In order to match a template, the template must contain controller and method tags to locate the controller method (which is the core information of MVC). Other tags in the template are mapped to parameters of the method (implemented by model binding).

When you add a routing map, you can provide a default value for the tag. Useful when the template does not contain controller and method tags. Templates can also contain optional tags corresponding to method parameters.

Let’s take a look at an example template:


contact/{controller=Home}/{action=Index}/{id?} 

Pay attention to the following points:

1. The tag is enclosed in curly brackets. Here are three Tags: controller, action, and ID.
2. The template contains a literal contact that matches the text in the URL.
3. Default values have been provided for controller (home) and action (index).
4. Optional tags are declared by question marks.

The following URL matches the template:

  1. /Contact / home / index / 1: all tags have values.
  2. /Contact / home / index: optional tag ignored.
  3. /Contact / home: action tag ignored, the default value of index will be used.
  4. /Contact: the controller and action tags are ignored and their default values of home and index are used, respectively.

General routing

For example, given a template:

1. The first tag is mapped to the controller
2. The second tag maps to the method
3. The third tag maps to the optional method parameter ID

You can also omit controllers and methods from the template as long as you provide them with default values. For example, the following route is mapped to address / one, because the required controller and method tags are provided through defaults:


routes.MapRoute(

    name: "goto_one",

    template: "one",

    defaults: new { controller = "Home", action = "PageOne" }); 

Note: Please add this specific route before the general route, because the route is executed according to the defined order. Once a route matches successfully, the whole matching process will end.

Since routing middleware only uses controller and method tags to map to a controller method, multiple methods with the same name in the same controller will throw an exception. To solve this problem, you can use the iactionconstraint features of methods (such as httpget, httppost, etc.):


[HttpGet("two")]

public IActionResult PageTwo()

{

  return Content("(GET) Work/Two");

}

 

[HttpPost("two/{id?}")]

public IActionResult PageTwo(int id)

{

  return Content($"(POST) Work/Two: {id}");

}

====start by sanshi=========================

In order to observe the exceptions of methods with the same name in the controller, we first need to modify the configure() method and add a development time exception handling middleware


public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

  if (env.IsDevelopment())

  {

    app.UseDeveloperExceptionPage();

  }

 

  app.UseMvc(routes => ....);

} 

Modify homecontroller:


public IActionResult PageTwo()

{

  return Content("(GET) Home/Two");

}

public IActionResult PageTwo(int id)

{

  return Content($"(POST) Home/Two: {id}");

} 

An overloaded function that seems normal, but it will throw an exception when put into the controller.

In the browser address bar, type: http://localhost : 65415 / home / pagetwo, view the exception page:

 

====end by sanshi=========================  

Characteristic routing

Feature routing is implemented by directly providing routing templates for controllers and methods.

We can use the [route] or [httpget] (or other verbs) properties to specify templates. These templates can contain literals and tags (not controller and method tags).

At runtime, the feature templates of controllers and methods are merged together. For example, in workcontroller, PAGEONE method can be accessed through / work / one


[Route("work")]

public class WorkController : Controller

{

  [Route("one")]

  public IActionResult PageOne()

  {

    return Content("Work/One");

  }

} 

Source code download

Original text: https://tahirnaushad.com/2017/08/20/asp-net-core-mvc-routing/

The above is the whole content of this article, I hope to help you in your study, and I hope you can support developeppaer more.