C# 应用数据约束时,基于路由的属性采用错误的方法

C# 应用数据约束时,基于路由的属性采用错误的方法,c#,asp.net-core,C#,Asp.net Core,我有以下API控制器类 using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; namespace Core31Test.Controllers { [ApiController] [Route("[controller]")] public class DataController : ControllerBase { [HttpGet]

我有以下API控制器类

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;

namespace Core31Test.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class DataController : ControllerBase
    {
        [HttpGet]
        [Route("query/{idr:int?}")]
        public string Get(int idr, [FromQuery] int id)
        {
            var idx = id == 0 ? idr : id;

            return $"Value: {idx}";
        }

        [HttpGet]
        [Route("query/{cityr}")]
        public string GetByCity(string cityr, [FromQuery] string city)
        {
            var cityx = string.IsNullOrEmpty(city) ? cityr : city;

            return cityx;
        }
    }
}
当我尝试按id进行查询时,基于路由的路径和查询字符串都起作用。当我尝试按城市查询时,只有基于路线的路径有效。查询字符串路径最终采用了错误的路径

例如:

http://localhost:51123/data/query/1
结果:数值:1

http://localhost:51123/data/query?id=1
结果:数值:1

http://localhost:51123/data/query/mycity
结果:我的城市

http://localhost:51123/data/query?city=acity
结果:值:0

在最后一种情况下,选择的路线不正确。为什么会发生这种情况?我如何修复它

编辑1

如果我将GetByCity方法的路由修改为下面给出的路由,则Get方法仍然处于选中状态。在这种情况下,两种方法都有可选的路由参数和查询字符串。由于Get路径指定输入为整数,我不理解为什么GetByCity方法要使用该方法。我想知道的是如何做到这一点

[Route("query/{cityr?}")]
在最后一种情况下,选择的路线不正确。为什么会发生这种情况?我如何修复它

不,不是。正在选择正确的预期路线。让我们仔细看看:

  • 路线是
    query?city=acity
  • 可采取的行动包括:
    • query/
      +可选的int参数(
      query/{idr:int?}
    • query/
      +必需的字符串参数(
      “query/{cityr}”

如果您仔细想想,
query/
不满足
query/
+必需的字符串参数,因为没有为
cityr
提供值,因此正确的路由是
idr
重载,因为该参数是可选的。

它选择了正确的路径,而不是您假设的错误路径。
{cityr}
部分不是可选的。所以当你发送
http://localhost:51123/data/query?city=acity
,该部分
{cityr}
缺失,这意味着它无法与方法
GetByCity
匹配。相反,它匹配route
query/{idr:int?}
,最后一种情况下缺少
idr
,查询
?city
不绑定到方法
Get
的任何参数。因此,
id
idr
都是
0
@KingKing修改路线没有什么区别。[Route(“query/{cityr?}”)]仍然转到Get而不是getByCityLook,在匹配路由和查找操作方法时,没有考虑像
query
。查询值并不总是需要相应的参数(绑定),因为操作代码可以通过查询值提供程序(像字典一样访问)轻松获取查询值。您不应该将您的API设计成这样一个模棱两可的选择。在最后一种情况下,首先声明哪个方法(使用
RouteAttribute
)的优先级更高。您可以尝试切换他们的声明顺序来查看。您可以显式地设置
顺序(在
[Route]
上),但实际上并不建议这样做。修改GetByCity的路由没有任何区别。换句话说,[Route(“query/{cityr?}”)]仍然使用错误的方法