Wednesday, January 10, 2018

Different types of Convention based Routing in ASP.NET MVC

1. Using Static URL segments in Routing


In routing, we can also specify a static segments and remaining as dynamically passed variable.
Fo this url http://localhost:63087/CustomController/Index

Index method of CustomController will be called.

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

For above if request is /Admin/Index than home controller will be called with specified action.

2. Defining variable length routing


This type of routing is used to accept any number of url arguments and popularly known as CatchAll scenario where any data after specific segments are caught.

routes.MapRoute("CatchAll", "{controller}/{action}/{id}/{*catchall}",
     new { controller = "RoutingStuffs", action = "CatchAll", id = UrlParameter.Optional });

In the above code, after id segments we have {*catchall} that catches all segments of data after id like below

http://localhost:63087/RoutingStuffs/CatchAll/50/Delete/And/Other/Parameter -
In this case controller is RoutingStuffs, action method is CatchAll, id is 50 and remaining url segments comes under catchall.

The CatchAll action method of the RoutingStuffs controller should be defined like this

public ActionResult CatchAll(string id = null, string catchall = null)
        {
            return View();
        }

Here, we get the catchall parameter value = "Delete/And/Other/Parameter".


3. Prioritizing controller by Namespaces in Routing

In case we have more than one controller with the same name in different namesapce, as a result it throws below error.

Multiple types were found that match the controller name RoutingStuffs. This can happen if the route that services this request ...... does not specify namespaces to search for a controler that match the request. If this is the ase, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

To overcome this issue,  we can specify namespace

routes.MapRoute("CatchAllPriorityHome", "Home/Route/{controller}/{action}/{id}/{*catchall}",
      new { controller = "RoutingStuffs", action = "CatchAll", id = UrlParameter.Optional },
      new[] { "MVCTraining5.Controllers" });

 routes.MapRoute("CatchAllPriority", "Route/{controller}/{action}/{id}/{*catchall}",
      new { controller = "RoutingStuffs", action = "CatchAll", id = UrlParameter.Optional },
      new[] { "MVCTraining5.Controllers.OtherFolder" });

In above code snippet, the first MapRoute method specify if the url starts with "Home/Route/....." then go for RoutingStuffs controller that is in the MVCTraining5.Controllers namespace, if not found then look for other namespaces.

The second MapRoute method specify that if the url starts with "/Route/........" then go for the RoutingStuffs controller that is in the MVCTraining5.Controllers.OtherFolder namespace.

4. Constraining Routes using Regular Expression or Hard coded values

We can also constraint the routes by specifying the Regular Expression for controller, action method etc.

routes.MapRoute("ConstrainRouteRA", "{controller}/{action}/{id}/{*catchall}",
   new { controller = "RoutingStuffs", action = "Index", id = UrlParameter.Optional },
   new { controller = "^R.*", action = "^Index$|^About$" });

Above route will be applicable to only those request whose controller starts with "R" or action method is either Index or About.

routes.MapRoute("ConstraintRouteHttp", "{controller}/{action}/{id}/{*catchall}",
  new { controller = "RoutingStuffs", action = "Index", id = UrlParameter.Optional },
  httpMethod = new HttpMethodConstraint("GET", "POST") });

Above route will be applicable to only those request whose controller name is RoutingStuffs, and request type is either "GET" or "POST".

routes.MapRoute("ConstraintRouteRange", "{controller}/{action}/{id}/{*catchall}",
  new { controller = "RoutingStuffs", action = "Index", id = UrlParameter.Optional },
  new
      {       
        id = new RangeRouteConstraint(10, 20)
     });

It is applicable if id is in between 10 and 20.

Note, that RangeRouteContraint and other value constraints are supported only in ASP.NET MVC 5+.

Similar to RangeRouteContraint, there are few more value constraints
BoolRouteConstraint - checks for value that can be parsed as boolean
DateTimeRouteConstraint - checks for value that can be parsed as date and time
AlphaRouteConstraint - checks for alphabets character either upper or lower case
IntRouteConstraint - checks for value that can be parsed as integer
MaxLengthRouteConstraint & MinLengthRouteConstraint - checks for maximum and minimum length of the characters

5. Custom constraint route in ASP.NET MVC


Think about a scenario, where a particular feature or style of your app doesn't work in Google chrome but works in all other browser like Internet Explorer and FireFox. In this case we can use custom constraint routing.

To define a custom constraint, we need to create a class file that looks something like

using System.Web;
using System.Web.Routing;

namespace MVCTraining5.Utility
{
    public class BrowserDetectConstraint : IRouteConstraint
    {
        string _userAgent = string.Empty;

        public BrowserDetectConstraint(string userAgent)
        {
            _userAgent = userAgent;
        }

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            return httpContext.Request.UserAgent != null
                && httpContext.Request.UserAgent.Contains(_userAgent);
        }
    }
}

When we inherit this class file with IRouteConstraint, we have to implement Match method. Here at the instantiation of the class we are passing the user agent to check, the same is being matched and returns true/false in the Match method.

The above custom constraint can be used like below

routes.MapRoute("ConstraintCustomChrome", "{controller}/{action}/{id}/{*catchall}",
  new { controller = "RoutingStuffs", action = "Index", id = UrlParameter.Optional },
  new
     {
       customConstraint = new Utility.BrowserDetectConstraint("Chrome")
     }, new[] { "MVCTraining5.Controllers.OtherFolder" });

routes.MapRoute("ConstraintCustom", "{controller}/{action}/{id}/{*catchall}",
  new { controller = "RoutingStuffs", action = "Index", id = UrlParameter.Optional }
  , new[] { "MVCTraining5.Controllers" });

The first MapRouote method of the above code use BrowserDetectConstraint by passing Chrome as user agent parameter. If the request comes with this user agent (i.e, from Google Chrome browser), RoutingStuffs controller from MVCTraining5.Controllers.OtherFolder is called otherwise second MapRoute executes and call the RoutingStuffs controller from MVCTraining5.Controllers namespace.

Some Key Points

1.  Controller value is required in default. If no controller defined within than project will compile but show error on view : controller is required.

2. In case of static url segment (If no controller is enclosed in in braces) it match the pattern only, if matches take the controller value from default.



Source : http://www.dotnetfunda.com/articles/show/3029/different-types-of-routing-in-aspnet-mvc

No comments:

Followers

Link