Endpoint routing in ASP.NET Core 2.2

Time:2019-9-6

Endpoint routing

In ASP.NET Core 2.2, a new routing called Endpoint routing is added. In this paper, the former routing system is called traditional routing.

This paper introduces the core functions and implementation methods of traditional routing and Endpoint routing through source code. The differences in specific functions can be found in official documents.

After upgrading to ASP.NET Core 2.2, Endpoint routing is automatically enabled. If you want to restore the previous implementation logic, you need to add the following code:


services.AddMvc(options => options.EnableEndpointRouting = false)
  .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

The source code analyzed in this paper is based on ASP.NET Core version 2.2.3.

Endpoint effect

The difference between Endpoint routing and traditional routing is that the relationship between Url and Action is handled in UseMvc. We can’t get the corresponding action from Url and process it.

Endpoint is the separation of the mapping relationship between Url and Action from Mvc as an independent middleware.

The benefit is that we can use some information on Controller and Action in other middleware, such as Attruibute.

The framework also provides LinkGenerator classes to generate links directly from Endpoint without requiring HttpContext information.

In addition, some RPS (Requests per Second) have been upgraded.

However, Endpoint is still invoked in UseMvc, and more open usage will be implemented in ASP.NET Core 3.0.

Enabling Endpoint Routing

See Github for the source code. You can also get the source code to see locally.

In the UseMvc method in line 72 of the MVcApplication Builder Extensions. CS file, we can see the following code:


var options = app.ApplicationServices.GetRequiredService<IOptions<MvcOptions>>();

if (options.Value.EnableEndpointRouting)
{
  ...
}
else
{
  ...
}

If is the logic of Endpoint routing, and else is the logic of traditional routing.

The construction of MvcOptions is as follows: EnableEndpoint Routing controls the default value through Compatibility Switch, which is why Compatibility Version. Version_2_2 enables Endpoint routing.


public MvcOptions()
{
  // ...
  _enableEndpointRouting = new CompatibilitySwitch<bool>(nameof(EnableEndpointRouting));
  // ...
}

Principle of Endpoint Routing Implementation

Lines 92-123 of the MVC Application Builder Extensions. CS file translate actions from all Controllers into Endpoints.

In the UseEndpoint Routing of line 129, an Endpoint Routing Middleware is added, which finds the corresponding Endpoint of the current route from all Endpoints, and then puts it into the Feature collection.

In the UseEndpoint of 132 lines, an Endpoint Middleware middleware is added, which takes out the Endpoint found in Endpoint Routing Middleware, finds the corresponding Controller and Action according to the MetaData information, and calls it.

In the UseMvc method, UseEndpoint Routing and UseEndpoint are two consecutive middleware, while UseEndpoint is the end of the request, which means that our custom middleware can not get Endpoint information.

But by calling UseEndpoint manually, we can still get the Endpoint routing information.

Use examples

Here’s an example of how to use it.

Define a LogAttribute class and include a Message attribute to declare use on Action.

Define an Endpoint Test Middleware middleware that outputs the Message attribute of LogAttribute.

Call UseEndpoint Routing manually, and then call the Endpoint Test Middleware middleware we defined.


// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseEndpointRouting();

  app.UseMiddleware<EndpointTestMiddleware>();

  app.UseMvc(routes =>
  {
    routes.MapRoute(
      name: "default",
      template: "{controller=Home}/{action=Index}/{id?}");
  });
}
// EndpointTestMiddleware.cs
public class EndpointTestMiddleware
{
  private RequestDelegate _next;

  public EndpointTestMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext httpContext)
  {
    var endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint;
    if (endpoint == null)
    {
      await _next(httpContext);
      return;
    }
    var attruibutes = endpoint.Metadata.OfType<LogAttribute>();
    foreach (var attribute in attruibutes)
    {
      Debug.WriteLine("------------------------------------------------------------------------");
      Debug.WriteLine(attribute.Message);
      Debug.WriteLine("------------------------------------------------------------------------");
    }
    await _next(httpContext);
  }
}
// LogAttribute.cs
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public sealed class LogAttribute : Attribute
{
  public LogAttribute(string message)
  {
    Message = message;
  }

  public string Message { get; set; }
}
// HomeController.cs
public class HomeController : Controller
{
  [Log("Index")]
  public IActionResult Index()
  {
    return View();
  }

  [Log("Privacy")]
  public IActionResult Privacy()
  {
    return View();
  }
}

In this way, we can get Endpoint information in our own middleware, find LogAttribute on Controller, and output Message.

summary

Endpoint is a new routing mechanism in ASP.NET Core 2.2. It solves the problem that traditional routing is difficult to extend, solves the problem that traditional routing is too coupled with MVC, and improves RPS.

In this paper, Endpoint routing is introduced, the implementation principle of Endpoint is briefly analyzed, and an example is given.

Reference link:

[ https://devblogs.microsoft.com/aspnet/asp-net-core-2-2-0-preview1-endpoint-routing/ ]
[ https://www.stevejgordon.co.uk/asp-net-core-first-look-at-global-routing-dispatcher ]
[ https://rolandguijt.com/endpoint-routing-in-asp-net-core-2-2-explained/ ]

The above is the whole content of this article. I hope it will be helpful to everyone’s study, and I hope you will support developpaer more.

Recommended Today

Hadoop MapReduce Spark Configuration Item

Scope of application The configuration items covered in this article are mainly for Hadoop 2.x and Spark 2.x. MapReduce Official documents https://hadoop.apache.org/doc…Lower left corner: mapred-default.xml Examples of configuration items name value description mapreduce.job.reduce.slowstart.completedmaps 0.05 Resource requests for Reduce Task will not be made until the percentage of Map Task completed reaches that value. mapreduce.output.fileoutputformat.compress false […]