PBMining

Searching...
Monday, June 11, 2012

Advance Routing in Asp.net MVC 3

3:59 AM

Introducing URL Patterns

The routing system works its magic using a set of routes. These routes collectively compose the URL schema or scheme for an application, which is the set of URLs that your application will recognize and respond to.
We don’t need to manually type out all of the individual URLs we are willing to support. Instead, each route contains a URL pattern, which is compared to an incoming URL. If the pattern matches the URL, then it is used by the routing system to process that URL.

Default url matching pattern of asp.net MVC is {Controller}/{action}. asp.net MVC match the url based on segment define on path. so above pattern can match URL.http://yoursite.com/Home/index but not http://yoursite.com/Home/index/param,because not segment define for Param in default route pattern.

Create and Registering Simple route

There are Two different way to create route using RouteCollection.MapRoute or Adding new instance of route to RouteCollection.

        Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
               routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

        routes.MapRoute("default", "{controller}/{action}"})

        'second way


        routes.Add("default", New Route("{controller}/{action}", rvd, New MvcRouteHandler))

    

In second approach we manually create RouteValueDictionary class instance and pass it to Route Constructor and using default MVC Routing handler.We can create custom route handler i will show you as we go in advance.

Define default Value in route

default values define in route serve as proxy when there is no matching value found for Placeholder define in URL Pattern.


        routes.MapRoute("default", "{controller}/{action}", New With {.controller = "Home", .Action = "Index"})



        Dim rvd As New RouteValueDictionary
        rvd.Add("Controller", "Home")
        rvd.Add("action", "Index")
        routes.Add("default", New Route("{controller}/{action}", rvd, New MvcRouteHandler))
        
    

This route will match following Urls.

  • mysite.com
  • mysite.com/Controller1
  • mysite.com/controller1/action

but not match this url because no any place holder found for last parameter in URL pattern.

mysite.com/controller1/action/param1

Using Static Segment in URL Pattern

Static segment is generally use for making route Pattern unique by prefixed Pattern with static word.

       routes.MapRoute("R3", "Test/{controller}/{action}", New With {.controller = "RouteTest", .action = "Index"})
    

In Above code we add static segment to route pattern will make route unique and make limited to particular part of our application consider it as Test.
above route will match the following Urls.

  • mysite.com/Test
  • mysite.com/Test/Controller
  • mysite.com/Test/Controller/Action

Consider the route ordering

when we add route to RouteCollection it added in which order they define in global.asax,MapRoute and Add Method of RouteCollection added route in the end of Collection.So we must consider the route ordering and define most specific route first.

        
                routes.MapRoute("R3", "{controller}/{action}", New With {.controller = "RouteTest", .action = "Index"})
               
                routes.MapRoute("R4", "X{controller}/{action}", New With {.controller = "RouteTest", .action = "Index"})


    

In above code ,in second route definition we add static segment X,and first one os simple route definition. if we request for URL.

mysite.com/XController/Action

this URL is caught by first route definition and it search for XController and return 404 - not found error page.if we comment first route then its work well because now its caught by second route definition and request for XController is become Controller because we define X as static segment.

Define Variable-Length Routes

Sometime we want to define undeterminate number of route segment so it can handle more parameter in route. you can handle this situation by define single segment using cacheall variable by prefixing *.

    routes.MapRoute("MyRoute", "{controller}/{action}/{*catchall}",
new { controller = "Home", action = "Index" });
    

In above code last url segment {*cacheall} will store all parameter after controller and action. and it maps below Urls.

  • mysite.com
  • mysite.com/Controller1/Action/
  • mysite.com/Controller1/Action/param1/param2/paramN

Prioritizing Controller By Namespace

In some large application it may be case where we have controller with the same name but resides in different namespace. when we request for particular Url in MVC and if route match it ,it start searching for named controller.and if it found more than one controller with same name then it give error like below.

Multiple type were found that match the controller named 'Home'...

to address this problem we can tell MVC framework to give the preference to certain namespace when searching for the named controller.


        routes.MapRoute("R12", "{controller}/{action}/{id}",
                               Nothing,
                               nothing,
                                {"ProMVC3_Test.ProMVC3_Test2"})


    

In above route definition we add string array in last parameter it define the namespace inside which route will begin search for controller. if controller not found in given namespace then MVC begin search in another namespace.we can define multiple namespace MVC will continue searching even it find the named controller in first namespace its give the same error if same named controller were found in both namespace.

we can tell MVC to look for the particular namespace.if controller not found in given namespace then not searching for elsewhere and give the error. we can do this by set the UseNamespaceFallback key of dataToken collection Property of route to False.

        Dim rt As Route = routes.MapRoute("R11", "{controller}/{action}/{id}",
                       New With {.controller = "RouteTest", .action = "Index", .id = UrlParameter.Optional},
                       {"MVC3_Test.ProMVC3_Test2"})

        rt.DataTokens("UseNamespaceFallback") = False
        
    

Routing Request Disk file

default MVC routing mechanism handle request for controller and action it doesn't routing through static content like Html files,images,javascript files and other disk files. but sometimes for security reason we want that static content should be routed through.we can enable this feature by setting RouteExistingFiles property of RouteCollection to True. see the below route definition

        Shared Sub RegisterRoutes(ByVal routes As RouteCollection)

        routes.RouteExistingFiles = True

        routes.MapRoute("Diskfile", "Content/StaticContent.htm",
        New With {.controller = "Account", .action = "Login"})

        End Sub          

    

when user request for Content/StaticContent.htm above route will handle that request and redirect user to Login page as we have not define any segment for controller and action route will take a default values. enabling disk file routing can effect the performance of our application because now it serve all files from disk if route match. we can decrease that overhead by ignoring request for some files.

routes.IgnoreRoute("Content/{filename}.css")

so now routing system know that request for CSS files should be ignored.

-->>> Constraining routes

1 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete

Write your review about this post.