Closed AnthonySteele closed 10 years ago
It's mostly working now, but there is this: http://stackoverflow.com/questions/20034983/mapmvcattributeroutes-this-method-cannot-be-called-during-the-applications-pre
I have put out a beta verions 0.0.1: http://www.nuget.org/packages/MvcRouteTester.MVC5/
Looks like getting Attribute routes working on Web controllers in ASP MVC 5 is going to be hard https://aspnetwebstack.codeplex.com/workitem/1445
Oddly, it works fine on Api controllers.
@AnthonySteele I don't know if it helps, but I was able to circumvent this exact problem. When I used dotPeek I discovered that there was an internal MapMvcAttributeRoutes
extension method that took in an IEnumerable<Type>
which is supposed to be a list of controller types. I'm not sure why that method isn't public instead of internal, but using reflection I was finally able to use MvcRouteTester with ASP.NET MVC 5. Here's my new extension method:
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
RouteConfig.RegisterRoutes(routes);
routes.MapMvcAttributeRoutesForTesting();
// Assert
routes.ShouldMap("~/").To<HomeController>(x => x.Index());
}
}
The main issue now is that inside RouteConfig.RegisterRoutes(routes)
I can't call routes.MapMvcAttributeRoutes()
, but instead I moved that call to my Global.asax.cs file. It's a hack, but it was the only way I could get it to work with a minimal amount of work.
Again, I don't know if it helps at all, but I thought I would share it anyway.
I'm trying this out, thanks so much! It seems to work, I'll see if anything can be done about the usability https://github.com/AnthonySteele/MvcRouteTester/commit/6d6fcf587598b570e3fd8638d0b653114e53721e
Awesome! MapAttributeRoutesInAssembly()
is a much better name than what I had. :+1:
My only concern is if the developers change/remove the method in RouteCollectionAttributeRoutingExtensions
since it is internal. I suppose you could check if mapMvcAttributeRoutesMethod
is null and give an appropriate error message if it is (e.g. "The implementation used for ASP.NET MVC 5 is no longer valid. Please update the MvcRouteTester NuGet package to get the latest version."). Hopefully by that time, the issue you mentioned above will have been resolved.
tidied up and pushed to nuget as MvcRouteTester.MVC5 v 0.0.2 http://www.nuget.org/packages/MvcRouteTester.MVC5/
chartek, would you like to put the code on the Stackoverflow question? IMHO it's good enough to be an accepted answer.
Cool, thanks! I went ahead and added the solution to Stackoverflow. Thanks for an awesome library! :smile:
@chartek How are you calling it from global.asax?
Apparently MvcRouteTester the nuget package does not work with the latest release of MVC - VS2013 and MVC5 A nuget package can include multiple binaries for different .Net versions, but not for different dependant library versions.
People seem to get around this by making different packages, e.g. http://www.nuget.org/packages/StructureMap.MVC4/ or http://www.nuget.org/packages/Ninject.Web.Mvc2/
I think I should do the same, using git branches here on github to track the different versions.
It seems that the minimum .Net framework version for MVC5 is .Net 4.5