我最近将我的项目升级到 ASP.NET MVC 5 并遇到了完全相同的问题。在使用dotPeek进行调查时,我发现有一个内部MapMvcAttributeRoutes
扩展方法,它有一个IEnumerable<Type>
作为参数的,它需要一个控制器类型列表。我创建了一个使用反射并允许我测试基于属性的路由的新扩展方法:
public static class RouteCollectionExtensions
{
public static void MapMvcAttributeRoutesForTesting(this RouteCollection routes)
{
var controllers = (from t in typeof(HomeController).Assembly.GetExportedTypes()
where
t != null &&
t.IsPublic &&
t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
!t.IsAbstract &&
typeof(IController).IsAssignableFrom(t)
select t).ToList();
var mapMvcAttributeRoutesMethod = typeof(RouteCollectionAttributeRoutingExtensions)
.GetMethod(
"MapMvcAttributeRoutes",
BindingFlags.NonPublic | BindingFlags.Static,
null,
new Type[] { typeof(RouteCollection), typeof(IEnumerable<Type>) },
null);
mapMvcAttributeRoutesMethod.Invoke(null, new object[] { routes, controllers });
}
}
这是我使用它的方式:
public class HomeControllerRouteTests
{
[Fact]
public void RequestTo_Root_ShouldMapTo_HomeIndex()
{
// Arrange
var routes = new RouteCollection();
// Act - registers traditional routes and the new attribute-defined routes
RouteConfig.RegisterRoutes(routes);
routes.MapMvcAttributeRoutesForTesting();
// Assert - uses MvcRouteTester to test specific routes
routes.ShouldMap("~/").To<HomeController>(x => x.Index());
}
}
现在的一个问题是,RouteConfig.RegisterRoutes(route)
我无法在内部调用routes.MapMvcAttributeRoutes()
,因此我将该调用移到了我的 Global.asax 文件中。
另一个问题是这个解决方案可能很脆弱,因为上面的方法RouteCollectionAttributeRoutingExtensions
是内部的,可以随时删除。一种主动的方法是检查mapMvcAttributeRoutesMethod
变量是否为空,如果是,则提供适当的错误/异常消息。
注意:这仅适用于 ASP.NET MVC 5.0。ASP.NET MVC 5.1 中的属性路由发生了重大变化,该mapMvcAttributeRoutesMethod
方法被移至内部类。