zoukankan      html  css  js  c++  java
  • net core3.1 和 net 5 下action重载问题

    1、问题

      最近将一个.net framework api 项目迁移到net core 3.1。其中有两个action是重载的,方法参数个数不一样。在.net framework下会自动根据请求参数个数进行路由匹配,但是在.net core3.1 下会报【The request matched multiple endpoints】异常。

    2、问题查找

      异常的原因在于匹配的多个节点路由。遇到此问题我的第一反映,我重写匹配endpoints相关方法不就行了。带着这个思路我开始看相关的源码,看其是如何进行endpoints注册和匹配的。

      相关注册源码地址:

      https://github.com/aspnet/Routing/blob/master/src/Microsoft.AspNetCore.Routing/Builder/EndpointRoutingApplicationBuilderExtensions.cs

      https://github.com/dotnet/aspnetcore/blob/c925f99cddac0df90ed0bc4a07ecda6b054a0b02/src/Mvc/Mvc.Core/src/Builder/ControllerEndpointRouteBuilderExtensions.cs

      https://github.com/dotnet/aspnetcore/blob/c925f99cddac0df90ed0bc4a07ecda6b054a0b02/src/Mvc/Mvc.Core/src/Routing/ControllerActionEndpointDataSourceFactory.cs#L10

      顺着代码看下GetRequiredService中都是实体类已经类是internal。这注册相关的代码好像不太好重写。

      那只能看匹配的相关代码试试。

      匹配相关源码地址:

      https://github.com/aspnet/Routing/blob/c28c7dea4e866ec5a0d33f0e290bc49baadb1c85/src/Microsoft.AspNetCore.Routing/EndpointRoutingMiddleware.cs

      https://github.com/aspnet/Routing/blob/c28c7dea4e866ec5a0d33f0e290bc49baadb1c85/src/Microsoft.AspNetCore.Routing/Matching/DfaMatcherFactory.cs#L9

      在DfaMatcherFactory中有一段代码:

      

     1 public override Matcher CreateMatcher(EndpointDataSource dataSource)
     2         {
     3             if (dataSource == null)
     4             {
     5                 throw new ArgumentNullException(nameof(dataSource));
     6             }
     7 
     8             return new DataSourceDependentMatcher(dataSource, () =>
     9             {
    10                 return _services.GetRequiredService<DfaMatcherBuilder>();
    11             });
    12         }
    View Code

       看着可以重写MatcherFactory对应的实现来达到目的。但是写完不知道对默认实现有没有影响,需要大量测试,有点耗时间。准备找另外一种解决方法。

    3、另一种思路

      既然重写有点耗时,那如果把已经注册好的endpoints中影响匹配的endpoint删掉不就行了。在源码中可以看到,endpoint都是放在EndpointDataSource中。

    4、问题解决

      在app.UseEndpoints(endpoints => 中的endpoints 有一个DataSources属性,类型是ICollection<EndpointDataSource>实际类型是List。遍历DataSource中Endpoints,找到需要删除的endpoint,然后将其删除即可。然后使用MapWhen单独注册这连个action路由即可。

    5、net 5 下问题再现

       在将.net core 3.1 发布到线上后。准备将项目升级到.net 5。在升级到.net 5后,那两个接口再请求时候再次报【The request matched multiple endpoints】。翻看官方.net core 升级.net 5 文档,上面也没有提endpoint相关逻辑修改。我只能进行调试,看看Startup.Configure中UseEndpoints有什么变化。经过仔细对比发现MapWhen中endpoints.DataSources有变化。只能再次修改MapWhen中endpoints.DataSources将问题解决

    6、最后

      上面的解决方法不怎么优雅,下面有空还是找找重写EndpointRoutingMiddleware中相关代码来进行实现。各位大神有什么好的方法也可以评论一下。

  • 相关阅读:
    第十一课:容器监控和Prometheus介绍
    第五课:单机编排利器:Docker Compose
    第四课:企业级镜像仓库Harbor
    第三课:快速部署LNMP平台
    负载均衡
    中间系统到中间系统IS-IS
    ansble 常识
    centos 的两种密码破解方式
    git在windos下使用
    git 本地仓库和远程仓库搭建
  • 原文地址:https://www.cnblogs.com/gsjlovenet/p/14394939.html
Copyright © 2011-2022 走看看