gpt4 book ai didi

asp.net-mvc - RouteAttribute 的 Order 在 IRouteConstraint 上被完全忽略

转载 作者:行者123 更新时间:2023-12-03 20:30:30 25 4
gpt4 key购买 nike

我们有一个 IRouteConstraint 被检查得比它应该的多得多。经过进一步测试,看起来 [Route] 上的 Order 被路由约束忽略了。

例如,如果我有以下约束:

public class TestConstraint : IRouteConstraint {
public bool Match(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
) {
Debug.WriteLine("TestConstraint");
return true;
}
}

然后连接起来:

constraintResolver.ConstraintMap.Add("testConstraint", typeof(TestConstraint));

并且有以下路由:

public partial class HomeController {
[Route("test/0", Order = 1)]
public ActionResult Test0() {
return Content("Test0");
}

[Route("{someParam}/{test:testConstraint}", Order = 10)]
public ActionResult Test1() {
return Content("Test1");
}
}

然后请求http://localhost/test/0,它会返回正确的内容(Test0),但是TestContraint.Match () 仍然执行。

我认为只有在 RouteTable 中遇到路由时才会执行路由约束,但它似乎在每个 可以匹配 的请求上运行它>[路线] 模式。

如果它有所作为,我们使用的是 ASP.NET MVC v5.2.4。

最佳答案

在 ASP.NET MVC 管道中,路由阶段和调用 Controller 操作的选择阶段是分开的。在路由阶段,您不能只选择第一个匹配操作并停止进一步查找。找到的 Action (严格来说是方法)可以在后期过滤。例如,它可能不满足应用的 Action 选择器(例如 NonAction 属性)。

这就是为什么基本的 Action 选择算法如下:

  1. 通过配置的路由传递请求 URL 并选择所有匹配的操作。
  2. 通过 Action 选择器传递所有匹配的 Action ,过滤掉不匹配的。
  3. 按路由顺序排列候选 Action 。

现在有以下选项:

  1. 未找到匹配的操作。请求结果为 404 错误。
  2. 多个匹配 Action 共享相同的最高顺序。抛出异常(“当前请求在以下操作方法之间不明确......”)。
  3. 只有一个匹配 Action 具有最高顺序(或一个 Action 完全匹配)。选择并执行操作。

如果您对相应的 ASP.NET MVC 源代码感兴趣,这里有一些引用资料:

IRouteConstraint.Match()System.Web.Routing.Route 中的 ProcessConstraint() 方法调用。调用堆栈中最近的方法,在路由集合级别上运行,是 System.Web.Mvc.Routing.RouteCollectionRoute 类中的 GetRouteData() 方法:

enter image description here

这是它的 source code :

public override RouteData GetRouteData(HttpContextBase httpContext)
{
List<RouteData> matches = new List<RouteData>();
foreach (RouteBase route in _subRoutes)
{
var match = route.GetRouteData(httpContext);
if (match != null)
{
matches.Add(match);
}
}

return CreateDirectRouteMatch(this, matches);
}

如您所见,当找到匹配的路由时,循环不会中断。

应用 Action 选择器、执行排序和选择 Action 候选的代码位于 DirectRouteCandidate.SelectBestCandidate() ( source code ) 中:

public static DirectRouteCandidate SelectBestCandidate(List<DirectRouteCandidate> candidates, ControllerContext controllerContext)
{
Debug.Assert(controllerContext != null);
Debug.Assert(candidates != null);

// These filters will allow actions to opt-out of execution via the provided public extensibility points.
List<DirectRouteCandidate> filteredByActionName = ApplyActionNameFilters(candidates, controllerContext);
List<DirectRouteCandidate> applicableCandidates = ApplyActionSelectors(filteredByActionName, controllerContext);

// At this point all of the remaining actions are applicable - now we're just trying to find the
// most specific match.
//
// Order is first, because it's the 'override' to our algorithm
List<DirectRouteCandidate> filteredByOrder = FilterByOrder(applicableCandidates);
List<DirectRouteCandidate> filteredByPrecedence = FilterByPrecedence(filteredByOrder);

if (filteredByPrecedence.Count == 0)
{
return null;
}
else if (filteredByPrecedence.Count == 1)
{
return filteredByPrecedence[0];
}
else
{
throw CreateAmbiguiousMatchException(candidates);
}
}

关于asp.net-mvc - RouteAttribute 的 Order 在 IRouteConstraint 上被完全忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49869484/

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