Jun 11, 2009

mvc routing

Routing is actually not part of the asp.net mvc component. But mvc depends on this asp.net components. To add a route to the route table, you can use the following code.

Route r = new Route("url", new SomeRouteHandler());
r.Constraints.Add("key", "value");
r.Defaults.Add("key", "value");
r.DataTokens.Add("key", "value");
RouteTable.Routes.Add("route_name", r);

// or you can write the code in .net 3.0 syntax, they do the same job
//but it looks cleaner.
 RouteTable.Routes.Add(new Route("url", new SomeRouteHandler())
 {
     Constraints = new RouteValueDictionary(new { key = value }),
     Defaults = new RouteValueDictionary(new { key = value }),
     DataTokens = new RouteValueDictionary(new { key = value }),
 });

asp.net mvc, add some extension method to the RouteCollection like the following.

public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
    if (routes == null) {
        throw new ArgumentNullException("routes");
    }
    if (url == null) {
        throw new ArgumentNullException("url");
    }

    Route route = new Route(url, new MvcRouteHandler()) {
        Defaults = new RouteValueDictionary(defaults),
        Constraints = new RouteValueDictionary(constraints)
    };

    if ((namespaces != null) && (namespaces.Length > 0)) {
        route.DataTokens = new RouteValueDictionary();
        route.DataTokens["Namespaces"] = namespaces;
    }

    routes.Add(name, route);

    return route;
}

This method create a route use MvcRouteHandler as IRouteHandler. So if use this method, the MVC component comes into play. So you can these extension method to simplify the mvc routing

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

The default values only work when every URL parameters after the one with default also has a default value assigned. So the following code doesn't work.

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

The following code demo a catch-all parameter

routes.MapRoute("r2", "catch/{*all}", new { controller = "test", action = "catch", all="empty" });

public string Catch(string all)
{
    return string.Format("

all:{0}

", all); }