"Customizing Routes in ASP.NET MVC"
In my earlier blog on "Basics of Route Config in Asp.Net MVC", I have discussed how the Routing is performed in Asp.Net MVC. Please go to following link for reference:
Basics of Route Config
Now we will see how to customize the routing mechanism in Asp.Net MVC to suit the needs of an application which requires more flexibility.
As I have already discussed in my above blog the default URL mapping in Asp.Net MVC is:
http://<domain>/{controller}/{action}/{id}
But there may be some cases where the project makes a requirement for the custom routes.
For example:
Route some specific requests to a specific Actions, Make the URLs well structured, etc.
Custom Routes:
Custom routes are also written inside the Route.Config file, above the Default route.
But why above the Default Route ?
Because the incoming URL is matched with all the route patterns in the Route.Config file from top to bottom and the first route pattern which successfully matches the URL is called and if the URL is not matched with any of the defined pattern the default Route pattern is called. This is the reason why to write the Custom routes above the Default route.
Routes Customization can be achieved in following ways:-
A. Modifying the URL Pattern
B. Modifying Route Default Options
C. Using Route Constraints
A. Modifying the URL Pattern :
As we have already discussed that the default URL pattern is:
http://<domain>/{controller}/{action}/{id}
But inorder to coustomize the route we can change this pattern as per the requirement of the project.
For example:
public/blog/{controller}-{action}/{postId}, {country}-{lang}/{controller}/{action}/{id},etc. these are all the valid patterns.
The URLs for the above pattern can be:
~/public/blog/posts-show/123 and ~/us-en/products/show/123 respectively.
B. Modifying Route Default Options:
In this method we can create our custom route over the default route.
For example:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// ALL THE PROPERTIES:
// rentalProperties/
routes.MapRoute(
name: "Properties",
url: "RentalProperties/{action}/{id}",
defaults: new
{
controller = "RentalProperty",
action = "All",
id = UrlParameter.Optional
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional }
);
}
In the above code we have a custom route name Poperties. Now for the incoming URL first the
Properties route will be checked if it does not matches the default route will be called.
C. Using Route Constraints:
We can also customize the route by using Constraints.
The constraints can be used in the following two ways:
1. Regular Expressions in Route Constraints
In this we provide a string that is interpreted as a Regular Expression to limit the ways a URL might match a particular route.
Let us take an example:
routes.MapRoute(
name: "BlogPost",
url: "blog/posts/{postId}",
defaults: new
{
controller = "Posts",
action = "GetPost",
},
);
The above pattern will match the following URL:
http://domain/blog/posts/123 but unfortunately it will also match the following URL:
http://domain/blog/posts/gimme
So the issue is to restrict the value of a route parameter to numeric values. For acheiving this we can rewrite the Route with the constraint:
routes.MapRoute(
name: "BlogPost",
url: "blog/posts/{postId}",
defaults: new
{
controller = "Posts",
action = "GetPost",
},
new {postId = @"\d+" }
);
Now this will accept only the numeric values as a route parameter.
2. Using IRouteConstraint:
In this we first create a class which implements IRouteConstraint. IRouteConstraint has a single method, "Match" which we implement in the class. We also create a constructor of the class to set the argument(s) required for the method.
Let us take an example:
Following is the Class name ExcludeController that implements IRouteConstraint. It also contains a Constructor and implements the Match method.
public class ExcludeController : IRouteConstraint
{
private readonly string _controller;
public ExcludeController(string controller)
{
_controller = controller;
}
public bool Match(HttpContextBase httpContext,
Route route, string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
// Does the _controller argument match the controller value in the route
// dictionary for the current request?
return string.Equals(values["controller"].ToString(),
_controller, StringComparison.OrdinalIgnoreCase);
}
}
Now adding the constraint to the route config file:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
},
constraints: new { controller = new ExcludeController("Configuration")}
);
Now if the incoming URL matches with the above default pattern then the Match() method of ExcludeController will be called which is our custom constraint. Now if the {controller} value in the incoming URL is 'Configuration' then the Match() method will return false and the route will reject the incoming URL.
In this way we can protect our Configuration Controller from access through the Default Route by unauthorised users.
Hope it Helps.... Happy Coding..!
0 Comment(s)