11

我正在测试 ASP MVC 路由。我在 ASP MVC 5.1 中遇到属性路由问题

当我有这样的控制器时:

public class FooController : Controller
{
    [Route("foo")]
    [HttpGet]
    public ActionResult Get()
    {
      .... 
    }

    [Route("foo")]
    [HttpPost]
    public ActionResult Post()
    {
      .... 
    }
}

然后为了测试哪个路由匹配特定请求,我调用routes.GetRouteData. 我得到一个System.Web.Routing.RouteData包含路由以及应该说明哪个控制器和操作匹配的值。

问题是这个路由现在是RouteCollectionRoute的一个实例, 这个内部类是对这两个动作的一组路由的包装器。控制器在 中RouteData.values,但动作不在。您可以使用routeData.Values["MS_DirectRouteMatches"] as IList<RouteData>.

在给出的示例中,列表中将有两个路由,用于两个操作方法。我需要知道哪些包含的路由实际上是匹配的,以便我可以读取匹配路由的操作方法名称是什么。我该如何解决这条路线?

我对拥有 a 的设计选择有点困惑RouteCollectionRoute。路由时,你有一个路由集合,然后你通过调用来解析一个 url 的路由GetRouteData。现在你有一条路线。但如果是RouteCollectionRoute这样,它仍然是路由的集合,并且路由解析还没有结束。拥有 RouteCollectionRoute 获得了什么?路由解析现在是一个两步过程吗?还是递归过程?

我知道我正在浏览 ASP MVC 的内部结构,但这是唯一的方法,因为它在设计时并没有考虑到这种可测试性。即使是像公开一些内部类或方法这样简单的事情也会有很大帮助!

4

2 回答 2

2

属性路由在 ASP.NET MVC 中比基于传统约定的要复杂一些。System.Web.Mvc.Controller.ExecuteCore()您可以从属性路由返回 null 的位置开始审核,GetActionName()并让操作选择器选择要执行的操作。然后你可以跳到System.Web.Mvc.ControllerActionInvoker.FindAction()那个神奇的地方,找到 RouteCandidates 然后通过 ActionNameSelectors、ActionSelectors 等过滤它们。

我提出了一个包含 ASP.NET MVC 逻辑的实现的拉取请求。

要补充的一件重要的事情:实现非常繁重,需要大量反思。请查看 ASP.NET 团队如何测试路由,例如在 AttributeRoutingTest.cs 中。您可以使用自己的 ControllerFactory 来返回模拟控制器,并返回它们的名称、参数等。在我看来,这会容易得多。

于 2014-03-26T15:49:03.727 回答
0

@Anthony,如果您只想查看任何给定 URL 遵循哪些路由,请加载Cobisi Routing Assistant扩展。

在 Visual Studio IDE 中,转到 Tools->Extension Manager...。然后,确保选择了 Online Gallery 选项卡并在搜索框中键入“cobisi”。安装扩展程序后,您将在工具菜单中获得一个名为 Cobisi (natch) 的新项目。

选择 URL Mapper,如果项目抱怨它被锁定,则解锁项目,然后输入 URL。当您单击 Map 按钮时,您将看到 URL 是如何路由的。恕我直言,如果您遇到路由问题,那就太棒了。

于 2014-03-25T16:41:51.090 回答