Generating Uri’s(Url’s) Matching Route in MVC

In the course of trying to get an MVC application working on IIS 6 we we have decided on some rules for generating Uri in an MVC application. The rules seek to ensure that all Uri generated will be correct no matter in what type of environment that we host our application. We are seeking to generate Uri that match a route as there may be situations where clients don’t want’ to use Wildcard Extension Mapping, and some that may, and some that will run it on IIS 7…

I may post something more about that soon, but for the moment I want to focus particularly on the generation of Uri outside of ActionLink and BeginForm etc.

The following code shows how to generate a Uri (in my case I just rendered it as text onto the page for testing purposes. So I did it all on the view.)

    <%
        var routeValues = new RouteValueDictionary(); 
        routeValues.Add("controller", "Home"); 
        routeValues.Add("Action", "Dogs"); 
        routeValues.Add("dogId", "15");  
    %>
    <%= RouteTable.Routes.GetVirtualPath(Html.ViewContext.RequestContext, routeValues).VirtualPath %>

If you have a route like this:

    public static void RegisterRoutes(RouteCollection routes) {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",                                              
            "{controller}/{action}/{id}",                           
            new { controller = "Home", action = "Index", id = "" } 
        );

    }

Then you will get a uri of :

    /Home/Dogs?dogId=15

IF on the other hand you have a route like this

    routes.MapRoute(
        "Default",                                              
        "{controller}.aspx/{action}/{id}",                      
        new { controller = "Home", action = "Index", id = "" }  
    );

(Notice the .aspx bit) You will get a Uri like this

    /Home.aspx/Dogs?dogId=15

The reason is that the code generated in the GetVirtualPath method takes into account the available routes in the route table when it generates all of the Uri. In other words it finds a route that matches the route values and then generates the Uri based on the route template (for lack of a better work) This is the same thing that the BeginForm and ActionLink helpers (and others)

The framework helpers also take into consideration whether your application in a virtual directory or not and also taked into consideration the virtual directory name.

So it you are generating Uri that is going to be used across different versions of IIS and you want to allow your application to be used with .aspx or .mvc extension (etc) or even extensionless routes, then you should consider using the build int helpers like BeginForm/EndForm, ActionLink etc and also make sure that when you generate Uri for things like images or links in JavaScript or other places that you use the method above or any related method to generate the URi so that they match one of your routes!

Some of the resources that we’ve used while looking at setup on IIS are in this post. And the place that I found the original code that showed how to generate correct Uri in ASP.NET MVC was here.

Scott Guthrie has a post on Url routing. It’s a bit old and may have a few inaccuracies due to changes in the framework as they developed it. This also might be useful!

Advertisements