Route Matching

Coordinator
Dec 2, 2011 at 2:57 PM

Okay, here is what I’m thinking…

Originally, I made this so that MatchesRoute would match as long as you passed in the correct controller and action, without regard to other route values in the request.

In other words, given the following route:

routes.MapRoute(
      "Default"// Route name
      "{controller}/{action}/{id}"// URL with parameters
      new { controller = "Home"action = "Index"id = UrlParameter.Optional }, // Parameter defaults
);

 … both of the following would return true:

tester.WithIncomingRequest("/foo/bar/5").MatchesRoute("Foo""Bar");  // true
tester.WithIncomingRequest("/foo/bar/5").MatchesRoute("Foo""Bar"new { id = 5 });  //true

 

That seemed pretty lame to me. I then decided to make it so that it would only match if you passed in all the route values, so I changed it to check for those.

tester.WithIncomingRequest("/foo/bar/5").MatchesRoute("Foo""Bar");  // false
tester.WithIncomingRequest("/foo/bar/5").MatchesRoute("Foo""Bar"new { id = 5 });  // true

 

Okay, so that’s all good. But of course then, the user is not only required to supply all the data that appears in the request, but also any default values that are defined in the route.

routes.MapRoute(
      "Default"// Route name
      "{controller}/{action}/{id}"// URL with parameters
      new { controller = "Home"action = "Index"id = "DefaultId"}, // Parameter defaults      
);

tester.WithIncomingRequest("/foo/bar").MatchesRoute("Foo""Bar");  // false
tester.WithIncomingRequest("/foo/bar").MatchesRoute("Foo""Bar"new{id = "DefaultId"}); //true

 

 Okay, that seems to make sense. But then, the library would throw an exception if the default value defined in the route was null.

routes.MapRoute(
      "Default"// Route name
      "{controller}/{action}/{id}"// URL with parameters
      new { controller = "Home"action = "Index"id = (int?)null}, // Parameter defaults      
);

tester.WithIncomingRequest("/foo/bar").MatchesRoute("Foo""Bar"new{id = (int?)null}); //exception thrown

 

wasn't exactly sure how to approach this.

1)      Make it so that user would not have to supply the default value if the default value defined in the route is null.

tester.WithIncomingRequest("/foo/bar").MatchesRoute("Foo""Bar"); // true

 

2)      Make it so that user would have to supply the default null value, altering the code so that it can detect matching nulls.

tester.WithIncomingRequest("/foo/bar").MatchesRoute("Foo""Bar"new{id = (int?)null}); // true

 

3)      Make it so that user never has to supply any default values defined in the route at all, but only those in the request.

 

Not sure option 3 is actually viable, since the request values and default values are mixed together in the route data.

I ended up selecting option 1, but I’m not sure that is the right way to go either. Now I’m thinking option 2 is the most consistent path.

Any thoughts on this?

Dec 2, 2011 at 3:39 PM

I would lean toward option 2 since that is explicitly describing the full route you expect to come back from a given URL. Of course, I don't yet know what, exactly, would need to change to make that work.

If we go that route, depending on how the comparison is changed, it may also fix the issue I found with routes that have non-string, non-null defaults.
Coordinator
Dec 2, 2011 at 3:52 PM

I will try to have a look at your fork later today, and plan to tackle this at the same time.

Coordinator
Dec 5, 2011 at 4:43 AM

Think we nailed all the remaining edge cases with version 0.9. Let me know if you think I missed anything.