I have two routing rules in an ASP.NET MVC application :
routes.MapRoute(
"Products AJAX",
"Products/Ajax/{action}",
new { controller = "Products" }
);
routes.MapRoute(
"Product",
"Products/{id}",
new { controller = "Products", action = "ViewProduct", id = "1001" }
);
The second rule here allows me to create a url /Products/1002
to view product 1002. This is the original sole rule I created.
I wanted to add some AJAX on the view to allow it to retrieve a simple string :
public class ProductsController : Controller {
public ContentResult GetStatus()
{
return new ContentResult()
{
Content = "Status is OK at " + DateTime.Now.ToLongTimeString()
};
}
}
This is why I added the first routing rule above. I wanted it to be a more specific URL that could be used to go to any other actions defined within my controller. (If I didnt have this rule it would attempt to find a product with the SKU of 'GetStatus' which is no good!)
So I thought ok thats fine, I just need to write my AJAX command in my view as :
<%= Ajax.ActionLink("Update Status", "AJAX/GetStatus", new AjaxOptions { UpdateTargetId = "status" })%>
I assumed this would call the link Products/AJAX/GetStatus
, which would trigger the first routing rule and correctly go to my controller's GetStatus method.
To my surprise the URL when I hover over this command in internet explorer (or view source) becomes /Products/AJAX/AJAX/GetStatus
.
So I'm thinking whaaat, and I backtrack to perform some detective work.
I change my first rule to :
MapRoute(
"Products AJAX",
"Products/Foo/{action}",
new { controller = "Products" }
);
and I change my action to
<%= Ajax.ActionLink("Update Status", "GetStatus", new AjaxOptions { UpdateTargetId = "status" })%>
To my amazement the URL generated for this ActionLink is actually /Products/Foo/GetStatus. This based on my first rule correctly forwards to my AJAX handler and everything works great. And of course a link of /Products/1003 would match the second rule and go to product 1003.
My application is complete! I'm happy - sort of.
But I don't know why! The ONLY place in my whole codebase where I have Foo
is in my mapping rule so how on earth is the Ajax.ActionLink able to figure out that I want that link?
Evidently there is some kind of 'clever' reverse mapping being done. I cant seem to find any documentation about this and would like to know more.
I think it must be parsing the FIRST rule it finds or something like that, but it seems a little scary since I like to know whats going on.
Note: There is a very nice article about routing - including generation of URLs from the routing table on ScottGu's blog. Unfortunately I coudlnt seem find an explanation of whats going on in my situation in that blog.