axe*_*ter 4 c# asp.net asp.net-core-mvc
我试图在我的Controller类中编写一个响应Http GET请求的方法.该应用程序是一个ASP .NET Core 2.0 API.
该方法如下所示:
[HttpGet("GetObjects/{parameter1?}/{parameter2:decimal?}.../{parameter29:bool?}"]
public IActionResult(List<string> parameter1 = null, decimal? parameter2 = null, ..., bool? parameter29 = null)
{
}
Run Code Online (Sandbox Code Playgroud)
当我去添加第30个参数时,我得到了这个异常:OverflowException:对于Decimal,值太大或太小.图片中的更多细节.
我已经尝试添加一个可空的字符串列表,一个可空的bool和一个可空的十进制作为参数.当我交换现有方法的参数时,它们都工作正常.
一旦我构建项目而不是运行/使用它,我就会看到这个错误.我在工作版本和失败版本之间进行的唯一更改是将/ {parameter29:bool?}(或任何其他类型的参数)添加到HttpGet属性路径的末尾.
我试图获取与此对象相关的数据库的所有条目.我检查哪些参数不为空,并相应地过滤条目列表.然后我返回一个过滤列表.
这确实是asp.net核心路由中的一个错误.看看RoutePrecedence.cs,我们看到:
// Compute the precedence for generating a url
// e.g.: /api/template == 5.5
// /api/template/{id} == 5.53
// /api/{id:int} == 5.4
// /api/template/{id:int} == 5.54
public static decimal ComputeOutbound(RouteTemplate template)
{
// Each precedence digit corresponds to one decimal place. For example, 3 segments with precedences 2, 1,
// and 4 results in a combined precedence of 2.14 (decimal).
var precedence = 0m;
for (var i = 0; i < template.Segments.Count; i++)
{
var segment = template.Segments[i];
var digit = ComputeOutboundPrecedenceDigit(segment);
Debug.Assert(digit >= 0 && digit < 10);
precedence += decimal.Divide(digit, (decimal)Math.Pow(10, i));
}
return precedence;
}
Run Code Online (Sandbox Code Playgroud)
此函数计算路径模板的优先级编号,以便可以按照评估路径的顺序对路径进行排序.例如,/api/template/{id}之前应该进行评估/api/template,因为前者比后者更具体.
计算方法的具体细节与此问题无关,因此我们可以减少它只留下相关部分:
for (var i = 0; i < template.Segments.Count; i++) {
... (decimal)Math.Pow(10, i);
}
Run Code Online (Sandbox Code Playgroud)
因此,对于路径的每个段,Math.Pow(10, segmentIndex)计算并转换为decimal.和decimal之间的最大可能值.因此,只要您的路由模板包含30多个部分 - 此代码无法计算其优先级值.Math.Pow(10, 28)Math.Pow(10, 29)
您可以在asp.net core github存储库中提交问题,但我怀疑它会有很高的优先级,因为我怀疑有30多个部分的路由在现实场景中使用过.
最好的解决方案是不使用这样的路线.使用查询字符串参数,或者在请求正文中POST的json模型.