如何在RouteCollectionRoute中找到正确的路线?

时间:2014-03-14 22:04:32

标签: asp.net-mvc asp.net-mvc-routing attributerouting asp.net-mvc-5.1

I am testing ASP MVC routes。我有an issue with attribute routes in 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>获取这些包含的路径。

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

我对有RouteCollectionRoute的设计选择感到有些困惑。 路由时,您有一个路由集合,然后通过调用GetRouteData来解析URL的路由。现在你有一条路线。但如果它是RouteCollectionRoute,那么仍然,路线和路线分辨率的集合还没有结束。有一个RouteCollectionRoute获得了什么?路线解决现在是一个两步过程吗?还是一个递归过程?

我知道我正在浏览ASP MVC的内部,但它是唯一的方法,因为它并没有考虑到这种可测试性。即使像exposing some internal classes or methods这样简单的事情也会有很大的帮助!

2 个答案:

答案 0 :(得分:2)

ASP.NET MVC中的属性路由比传统的基于约定更复杂。您可以从System.Web.Mvc.Controller.ExecuteCore()开始审核,其中GetActionName()为属性路由返回null,让操作选择器选择要执行的操作。然后你可以跳转到System.Web.Mvc.ControllerActionInvoker.FindAction()完成所有魔法并找到RouteCandidates然后通过ActionNameSelectors,ActionSelectors等过滤它们。

我使用包含ASP.NET MVC逻辑的实现创建了a pull request

要添加的一件重要事情: 实施非常繁重,反思很多。请查看ASP.NET团队如何测试路由e.g. in AttributeRoutingTest.cs。您可以使用自己的ControllerFactory,它将返回模拟控制器,并返回其名称,参数等操作。在我看来,这会更容易。

答案 1 :(得分:0)

@Anthony,如果您只想查看任何给定网址所遵循的路线,请加载Cobisi Routing Assistant分机。

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

选择URL映射器,如果项目抱怨它被锁定,则解锁项目,然后输入URL。单击“映射”按钮时,您将看到URL的路由方式。如果您遇到路由问题,那就太棒了。恕我直言。