ASP.NET MVC: Register a Route with a Parameter Constraint and a Default Value Defined in the Action Method


This weekend I was playing around with the routing configuration for an ASP.NET MVC project and ran into an interesting situation. I created a simple test project with a ProductsController containing and action method named List and as well its corresponding view. The List action method accepted an integer parameter named page that would indicate which page of the catalog to display.

I wanted to setup the routes so that the url ~/Catalog (not specifying any page parameter) would be mapped to the List action method so that the first page of the catalog would be displayed. Conversely, if the url ~/Catalog/2 was used, the List action method would be called and the second page would be displayed. This is actually a pretty simple task; all you need to do is set the page parameter in the route as optional as follows:

routes.MapRoute(null, 	// Route Name
                "Catalog/{page}",	// Url to match
                new { controller = "Products", action = "List", page = UrlParameter.Optional } 	// Default values
                );

This simple ASP.NET MVC 101 route works great but the one issue is that this route will match the url ~/Catalog/abc as well and attempt to cast the string ‘abc’ to an integer and cause the application to fail. My first thought was to simply put a constraint on the page parameter as follows to indicate that only digits could be accepted.

routes.MapRoute(null, 	// Route Name
                "Catalog/{page}",	// Url to match
                new { controller = "Products", action = "List", page = UrlParameter.Optional }, 	// Default values
                new { page = @"\d+" } 	// Parameter constraints
                );

This solved the above mentioned problem so that the url ~/Catalog/abc was no longer handled by this route. But, this created another problem, since I put the constraint on the page parameter that it had to be a digit value, this route no longer matched the url ~/Catalog. The simplest solution to this is replace the UrlParameter.Optional value assigned to the page parameter in the default values collection with the value 1 or whatever your default value is. If you do this and navigate to the url ~/Catalog, the ASP.NET MVC framework will automatically pass in the default value of 1 you supplied when register the route. But generally I like to specify the default values to my action methods using the [DefaultValue] attribute or the .NET Framework 4 syntax for specifying optional parameters as shown below.

public ActionResult List(int page = 1)
{
     // Method logic
}

Since I am looking at my controller code much more the the code used for registering routes, I am reminded that a default value is being provided to the method if one is not present in the url or the query string. Purely a personal preference, but one that I like to follow.

After much research, I concluded that there is no way to allow the user to enter both ~/Catalog and ~/Catalog/2 and to provide the default value along with the action method in a single route definition. In order to accomplish what I desired, the following two routes needed to be registered:

// Matches ~/Catalog/2
routes.MapRoute(null,	// Route Name
                "Catalog/{page}",	// Url to match
                new { controller = "Products", action = "List" },	// Default values
                new { page = @"\d+" }	// Parameter constraints
                );

// Matches ~/Catalog
routes.MapRoute(null,	// Route name
                "Catalog",	// Url to match
                new { controller = "Products", action = "List" }	// Default values
                );

If anyone has a solution to this using only one route, please let me know.

About these ads

4 Responses to “ASP.NET MVC: Register a Route with a Parameter Constraint and a Default Value Defined in the Action Method”

  1. Ferline Says:

    Thanks for the information of your

  2. raduenuca Says:

    See my last post from the thread you started on the ASP.NET Forums.

    http://forums.asp.net/t/1640599.aspx

    I belive I’ve found a solution

  3. Shivam Mishra Says:

    This is one of the best articles I read online. No crap, just useful information. Very well presented. Check this link too its having collection of asp.net mvc interview question and answer…

    http://www.mindstick.com/Interview/1211/What%20is%20Routing%20in%20ASP%20NET%20MVC

  4. Lelala Says:

    Will this work with route names with dashes “-” in it?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 70 other followers

%d bloggers like this: