Friday, 7 October 2011

MVC3 Routing and Segment Variable Quirks

Imagine our application has a single route, as follows:

routes.MapRoute("MyRoute", "{controller}/{action}/{color}/{page}");

Now imagine that a user is currently at the URL /Catalog/List/Purple/123, and we render a link as follows:

@Html.ActionLink("Click me", "List", "Catalog", new {page=789}, null)

You might expect that the routing system would be unable to match the route, because we have not supplied a value for the color segment variable, and there is no default value defined. You would, however, be wrong. The routing system will match against the route we have defined. It will generate the following HTML:

<a href="">Click me</a>

The routing system is keen to make a match against a route, to the extent that it will reuse segment variable values from the incoming URL. In this case, we end up with the value Purple for the color variable, because of the URL from which our imaginary user started.

This is not a behavior of last resort. The routing system will apply this technique as part of its regular assessment of routes, even if there is a subsequent route that would match without requiring values from the current request to be reused. The routing system will reuse values only for segment variables that occur earlier in the URL pattern than any parameters that are supplied to the Html.ActionLink method. Suppose we tried to create a link like this:

@Html.ActionLink("Click me", "List", "Catalog", new {color="Aqua"}, null)

We have supplied a value for color, but not for page. But color appears before page in the URL pattern, and so the routing system won't reuse the values from the incoming URL, and the route will not match.

The best way to deal with this behavior is to prevent it from happening

No comments:

Post a Comment