You should have two routes:
First, for pagination (using the default controller and action):
routes.MapRoute( "Default", // Route name "home/{id}/{page}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional, page = UrlParameter.Optional } // Parameter defaults );
Last route for all controllers:
routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}/{page}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional, page = UrlParameter.Optional } // Parameter defaults );
Thus, with the above routes / home / 1 / page5, the action of the index of the home controller will be processed, but someController / someAction / 1 / page5 will be the second route.
You should know that you first need to host routes that process fewer URLs, and not shared routes, for example, the second route is higher for all controllers.
Also, inside the controller action, you can re-specify the route parameter as follows:
string page = RouteData.Values["page"];
therefore, for url home / 1 / page5 in the above sample page will be equal to "page5", than you can parse this line to get the page number.
As for me, I use the following method to get parameters from route data, message body, query string:
protected T GetQueryParam<T>(String name, T defValue = default(T)) { String param = HttpContext.Request.QueryString.Get(name); if (String.IsNullOrEmpty(param)) param = HttpContext.Request.Params[name]; if ( String.IsNullOrEmpty(param)) param = (String) RouteData.Values[name] ?? String.Empty; if (String.IsNullOrEmpty(param) ) return defValue; return (T)Convert.ChangeType(param, typeof(T)); }
So, if you need a page using the method above, you just need to do the following:
var page = GetQueryParam<string>("page");// in case if page parameter not exists default value for type will be returned