问题描述
我在使用ASP的MVC V5解决方案在测试项目中一个非常简单的测试和属性的路由。属性路由和 MapMvcAttributeRoutes
方法是ASP MVC的第5部分。
I have a very simple test in a test project in a solution using ASP MVC V5 and attribute routing. Attribute routing and the MapMvcAttributeRoutes
method are part of ASP MVC 5.
[Test]
public void HasRoutesInTable()
{
var routes = new RouteCollection();
routes.MapMvcAttributeRoutes();
Assert.That(routes.Count, Is.GreaterThan(0));
}
其结果是:
System.InvalidOperationException :
This method cannot be called during the applications pre-start initialization phase.
大部分的答案,这样的错误消息都涉及在的web.config
文件配置的会员供应商。该项目既没有会员供应商或<$ C $ C>的web.config 文件,使错误似乎可以被发生某些其他原因。如何移动的code出这个pre-启动状态,使测试能够运行?
Most of the answers to this error message involve configuring membership providers in the web.config
file. This project has neither membership providers or a web.config
file so the error seems be be occurring for some other reason. How do I move the code out of this "pre-start" state so that the tests can run?
相当于code关于 ApiController
属性后, HttpConfiguration.EnsureInitialized工作正常()
被调用。
The equivalent code for attributes on ApiController
works fine after HttpConfiguration.EnsureInitialized()
is called.
推荐答案
我最近升级我的项目ASP.NET MVC 5和经历完全一样的问题。当使用进行调查,我发现有一个内部 MapMvcAttributeRoutes
有一个的IEnumerable&LT;类型和GT; 作为预计控制器类型的列表中的参数。我创建了一个使用反射和让我来测试我的基于属性的路线了新的扩展方法:
I recently upgraded my project to ASP.NET MVC 5 and experienced the exact same issue. When using dotPeek to investigate it, I discovered that there is an internal MapMvcAttributeRoutes
extension method that has a IEnumerable<Type>
as a parameter which expects a list of controller types. I created a new extension method that uses reflection and allows me to test my attribute-based routes:
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 });
}
}
这里是我如何使用它:
And here is how I use it:
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(路线)
我不能叫 routes.MapMvcAttributeRoutes()
等等我感动的是调用我的Global.asax文件来代替。
One problem now is that inside RouteConfig.RegisterRoutes(route)
I cannot call routes.MapMvcAttributeRoutes()
so I moved that call to my Global.asax file instead.
另一个值得关注的是,该解决方案可能是易碎由于在 RouteCollectionAttributeRoutingExtensions
上述方法是内部和可以在任何时候被除去。积极主动的办法是检查,看看是否 mapMvcAttributeRoutesMethod
变量为空,并提供相应的错误/ exceptionmessage如果是
Another concern is that this solution is potentially fragile since the above method in RouteCollectionAttributeRoutingExtensions
is internal and could be removed at any time. A proactive approach would be to check to see if the mapMvcAttributeRoutesMethod
variable is null and provide an appropriate error/exceptionmessage if it is.
注意:这仅适用于ASP.NET MVC 5.0。有归因于路由ASP.NET MVC 5.1和 mapMvcAttributeRoutesMethod
方法显著的变化被转移到一个内部类。
NOTE: This only works with ASP.NET MVC 5.0. There were significant changes to attribute routing in ASP.NET MVC 5.1 and the mapMvcAttributeRoutesMethod
method was moved to an internal class.
这篇关于MapMvcAttributeRoutes:此方法不能在应用程序的pre-启动初始化阶段被称为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!