How does MVC routing understands the URL? - asp.net-mvc

Global.asax.cs has the following code on initialization:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
What I'm asking is, how does it know that what it gets for "{controller}" will be the name of the Controller class to be invoked? Are there tokens defined somewhere? if so, can I list them?
If I define additional tokens (like "{lang}") will it assume they are additional parameters?
(I'm developing a custom URL rewrite/redirect handler, and I need it to work with MVC...)
What is the most practical way to define custom patterns and "aliases" for URLs?

The Mvc runtime has the controller and action tokens hardcoded. In addition there is also "area" but thats about it.

#TDaver If I define additional tokens (like "{lang}") will it assume they are additional parameters?
yes. If you define, for instance, a parameter like lang, it wil detect it. Think about like that, it will be the querystring field called lang of the page. and you can create a route for a pretyy url. Like below;
routes.MapRoute(
"Default", // Route name
"{lang}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
so the url will be like ; http://example.com/en/home/about
Also, the most important part of routing is to understand that the routes will be picked by order. for instance, if you have multiple routes matching your current request, the first route will be picked by MVC Framework.
I reccomend you to have a look at phil haccked's RouteDebugger
Also you can create route constraints for advanced routing options as well.

Related

When are default route values used?

I'm confused about default routing values. Here's the default route in an MVC app:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I don't understand why it specifies a default value for, say, {controller}, because it seems to me that this route won't ever be used unless the user requests a url like /xyz/dosomething/123, and in that case the controller is simply xyz, and we don't need the default value.
So, with a route like this, when would the default controller and action values ever be used?
It would be used if you don't specify them in the url : http://whatever.com will be treated as http://whatever.com/Home/Index.
The default controller and action will be used when the page / is requested, i.e. when someone browses to just your domain address, e.g. http://www.mydomain.com.

MapRoute without affecting ActionLinks

Typically I want the default route used when generating URLs ("backwards" mapping), even if I've added alternate or legacy routes to reach an action ("forwards"):
routes.MapRoute("Legacy", "legacy/home/index", // want forward-only mapping!
new { controller = "Home", action = "Index" };
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
In this case, I'd still want the default route used when I call:
#ActionLink("Index", "Home") // generates legacy URLs ;(
In the thread: Routing legacy requests with and without querystring (issue #1), the solution is to add two MapRoute statements for each legacy route, or specify the route name in each ActionLink call.
Is there a way to define a route used only for URL -> Action mapping, not the inverse?
I can't find a way to have the route statements apply only one way, so I installed the IIS URL Rewrite module. This works to rewrite the URL transparently, or 301-redirect it in the case of legacy URLs.
It's a more maintainable solution than editing the global.asax anyway.

Hide params in url by asp.net mvc routing

I have an asp.net mvc 2 application. I get a page with the url http://localhost/Object/ChangeObject/108?MtRid=216584. I want to route it like this: http://localhost/Object/ChangeObject.
How to write a route for this?
There are more than one way to do this:
Try to modify the methode "application_beginrequest" of "Global.asax" This method is called every time some request is made to the website.
Take a look at this example
URL Routing - By adding custom URL Route mapping rules before the default one as described in this article
try this
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}/{MtRid}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional, MtRid = UrlParameter.Optional} // Parameter defaults
);

ASP.MVC 3 routing : how to get url with default action included?

Suppose I have the following routing
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
Now, when you generate an url using Url.Action("Index","MyController") you will get as expected : /MyController
But in one exceptional case, I would like to get the full url /MyController/Index
(without changing the routing)... does anyone know if this is possible?
It is possible. But you need to modify the routing.
Create an own routing class that derives Route
Override the GetVirtualPath() method to include /index for the pages that needs it.
Configure the default route using your routing class instead.
I am afraid this is not possible. And it shouldn't matter as both urls will resolve to the same controller action.

MVC Routing: Trying to get dynamic root value working

I am trying to define dynamic sections of my site with the root url of the site. I am having some trouble defining the right MVC Route for it. Can someone please help.
My desired url will look like this: http://website.com/[dynamic-string]
But I have other standard pages like: http://website.com/about or http://website.com/faq or even just http://website.com.
My routes don't work correctly with that dynamic string. As shown below.
This is the route for the dynamic-string.
routes.MapRoute(
"CommunityName", // Route name
"{communityName}", // URL with parameters
new { controller = "Community", action = "Community", communityName = UrlParameter.Optional }
);
This is the route for all other STANDARD PAGES
routes.MapRoute(
"Default", // Route name
"{action}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
My routes just don't match up. Everything either gets diverted to one or the other route depending on which route is declared first.
There is no difference between the two routes you mention. How can MVC know which url should be mapped to communityName and which to action? Any url can match both.
You can define your standard pages as a route (before the CommunityName route) or you can catch them in your Community action, see if the name matches a function in your Home controller and then call the right action function.
I've never done this before but you might be able to create a more intelligent routehandler that looks at your controller actions, checks if the action really exists and if true selects that route.
this is beacuse the routes are effectively the same. When you declare the action route you do not state any constraints to the route, for this reason anything will be assumed to be a the action name.
If you want two routes to capture at the same level then you must constrain the action names to those that exist on your controller, this way if it does not match it will pass to the next route.
You can see an example of and advanced constraint here:
http://blogs.planetcloud.co.uk/mygreatdiscovery/post/Custom-route-constraint-to-validate-against-a-list.aspx

Resources