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.
Related
.NET MVC. I am having some problems defining and using custom routes.
I have a controller with just 2 actions. These action methods receive 2 parameters each. I have added a custom route in RouteConfig.cs (before the default route), like this
routes.MapRoute(
name: "customRoute",
url: "MyController/{action}/{entityType}/{id}",
defaults: new { controller = "MyController", action = "Index", entityType = UrlParameter.Optional, id = UrlParameter.Optional }
);
this works if MyController does contain an Index method (and corresponding view).
the problem is, MyController does not contain an Index method (only the 2 action methods refered before), and I want the route.default to be something like Home/Index instead. but if I change the route to this:
routes.MapRoute(
name: "customRoute",
url: "MyController/{action}/{entityType}/{id}",
defaults: new { controller = "Home", action = "Index", entityType = UrlParameter.Optional, id = UrlParameter.Optional }
);
it does not work. Apparently, the controller in route.url must be the same as the one in route.defaults...
CORRECTION: the route works for a correct url, but for an incorrect one (for example adding another parameter at the end) it shows 404 error (makes sense, because MyController.Index does not exists)
so, how can this be achieved?
url: "MyController/{action}/{entityType}/{id}"
Here, what you are saying is the URL pattern for your custom route should start with MyController(My/).
If the url pattern does not match with the configured routes(including the default one) you will have 404 Error.
I can suggest 2 ways of achieving what you want...
Either create a third method in your MyController that will act as the default one and its task would be to redirect to Home/Index.
Or
Create a new method in Home controller having parameters for entityType and Id.
You can't create an overload for Home/Index because you can only have a maximum of 2 action methods with the same name on a controller.
See this.
Routing: The current request for action [...] is ambiguous between the following action methods
I have default routing set for my mvc application like:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
I have Home controller with Index() and About(). Tell me please how to modify routing to get both domain.com/Index and domain.com/About urls?
Thank you
Add this before your default route. By adding it before the default route, if it matches it will be used to set the RouteDictionary values. Untested, but it should map urls that only have a single component that is either index or about. Note, that this assumes you don't have an index or about controller. The routing constraint is important as it keeps it from matching on each controller's index action, e.g., controller/.
routes.MapRoute(
"IndexOrAbout",
"{action}",
new { controller = "home", action = "index", id = "" },
new
{
action = "(index)|(about)"
}
);
Note, if you need to expand this to more top-level routes or make it more dynamic you could use a custom routing constraint that could draw the top-level values from a database or configuration. At that point, you'd probably want to change it from using the action parameter to the id parameter and have a single action that use the id to determine what to show rather than have an action per value.
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.
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
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.