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.
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
This comment has been removed by a blog administrator.
ReplyDelete