gpt4 book ai didi

ASP.NET Core 2.2中的Endpoint路由详解

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章ASP.NET Core 2.2中的Endpoint路由详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

Endpoint路由 。

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

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

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

?
1
2
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 方法中我们可以看到以下代码:

?
1
2
3
4
5
6
7
8
9
10
var options = app.ApplicationServices.GetRequiredService<IOptions<MvcOptions>>();
 
if (options.Value.EnableEndpointRouting)
{
   ...
}
else
{
   ...
}

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

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

?
1
2
3
4
5
6
public MvcOptions()
{
   // ...
   _enableEndpointRouting = new CompatibilitySwitch< bool >(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 中间件.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 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();
   }
}

这样的话,我们可以在我们自己的中间件中拿到 Endpoint 信息,然后找到 Controller 上的 LogAttribute ,然后输出 Message.

总结 。

Endpoint 是ASP.NET Core 2.2中一种新的路由机制,它解决了传统路由难以扩展的问题,解决了传统路由与MVC过于耦合的问题,并提升了一定的RPS.

本文介绍了Endpoint路由,简单分析了Endpoint的实现原理,并给出了一个使用的示例.

参考链接:

[ 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/ ] 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.

原文链接:http://www.cnblogs.com/Weilence/p/10616567.html 。

最后此篇关于ASP.NET Core 2.2中的Endpoint路由详解的文章就讲到这里了,如果你想了解更多关于ASP.NET Core 2.2中的Endpoint路由详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com