ASP.NET Core 2.2中Endpoint路由的作用是什么
创始人
2024-11-27 15:23:39
0次

Endpoint路由

在ASP.NET Core 2.2中,新增了一种路由,叫做 Endpoint (终结点)路由。本文将以往的路由系统称为 传统路由 。

本文通过源码的方式介绍传统路由和 Endpoint 路由部分核心功能和实现方法,具体功能上的差异见 官方文档 。

在升级到ASP.NET Core 2.2后,会自动启用 Endpoint 路由。如果要恢复以往的实现逻辑,需要加入以下代码:

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

本文分析的源代码基于ASP.NET Core 2.2.3版本的 源代码 。

Endpoint作用

Endpoint 路由与传统路由的区别在于,传统路由 Url 与 Action 对应关系的处理是在 UseMvc 中做的。我们无法根据 Url 获取对应的 Action 然后进行处理。

Endpoint 就是将 Url 与 Action 的映射关系从 Mvc 中拆离,作为独立使用的中间件。

由此带来的好处是我们可以在其他的中间件中使用 Controller 和 Action 上的一些信息,例如 Attruibute 。

框架也提供了 LinkGenerator 类来直接根据 Endpoint 生成链接,不再需要 HttpContext 的信息。

另外也提升了一些RPS(Requests per Second)。

不过目前 Endpoint 依然是在 UseMvc 中调用,更多开放的使用方式会在ASP.NET Core 3.0中实现。

启用Endpoint路由

源代码见 Github 。也可以获取源代码到本地看。

在 MvcApplicationBuilderExtensions.cs 文件72行的 UseMvc 方法中我们可以看到以下代码:

var options = app.ApplicationServices.GetRequiredService>();

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

if 之中是 Endpoint 路由的逻辑, else 是传统路由的逻辑。

而 MvcOptions 的构造方法如下所示, EnableEndpointRouting 是通过 CompatibilitySwitch 来控制默认值的,这就是 CompatibilityVersion.Version_2_2 启用 Endpoint 路由的原因。

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

Endpoint路由实现原理

在 MvcApplicationBuilderExtensions.cs 文件的92-123行的代码是将所有的 Controller 中的 Action 转换成 Endpoint 。

在129行的 UseEndpointRouting 中,添加了一个 EndpointRoutingMiddleware 的中间件,这个中间件就是从所有的 Endpoint 中找到当前路由对应的 Endpoint ,然后放到 Feature 集合中。

在132行的 UseEndpoint 中,添加了一个 EndpointMiddleware 中间件,这个中间件是将 EndpointRoutingMiddleware 中找到的 Endpoint 取出,根据其中的 MetaData 信息,找到对应的 Controller 和 Action ,并调用。

在 UseMvc 方法里, UseEndpointRouting 和 UseEndpoint 是连续的两个中间件,而 UseEndpoint 是请求的结束,这意味着我们自定义的中间件无法取得 Endpoint 信息。

但是通过手动调用 UseEndpoint ,我们还是可以拿到 Endpoint 路由信息的。

使用示例

下面展示一个使用示例。

定义一个 LogAttribute 类,并包含一个 Message 属性,在 Action 上声明使用。

定义一个 EndpointTestMiddleware 中间件,输出 LogAttribute 的 Message 属性。

手动调用 UseEndpointRouting ,然后调用我们定义的 EndpointTestMiddleware 中间件。

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

  app.UseMiddleware();

  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()?.Endpoint;
    if (endpoint == null)
    {
      await _next(httpContext);
      return;
    }
    var attruibutes = endpoint.Metadata.OfType();
    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();
  }
}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...