Asp.net MVC routing ambiguous, two paths for same page - asp.net-mvc

I'm trying out ASP.NET MVC routing and have of course stumbled across a problem. I have a section, /Admin/Pages/, and this is also accessible through /Pages/, which it shouldn't. What could I be missing?
The routing code in global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Pages", // Route name
"Admin/Pages/{action}/{id}", // URL with parameters
// Parameter defaults
new { controller = "Pages", action = "Index", id = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
// Parameter defaults
new { controller = "Home", action = "Index", id = "" }
);
}
Thanks!

I'd suggest adding an explicit route for /Pages/ at the beginning.
The problem is that it's being handled by the Default route and deriving:
controller = "Pages"
action = "Index"
id = ""
which are exactly the same as the parameters for your Admin route.

For routing issues like this, you should try out my Route Debugger assembly (use only in testing). It can help figure out these types of issues.
P.S. If you're trying to secure the Pages controller, make sure to use the [Authorize] attribute. Don't just rely on URL authorization.

You could add a constraint to the default rule so that the {Controller} tag cannot be "Pages".

You have in you first route {action} token/parameter which gets in conflict with setting of default action. Try changing parameter name in your route, or remove default action name.

Related

I want to call controller's Default action.

Example : My User will enter www.xyz.com/Promo/PROMO123
where "PROMO123" is value, which i require.
above code produces error :
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
However
www.xyz.com/Promo/Index/PROMO123 will work properly,
but i dont want this.
How can i archive this
www.xyz.com/Promo/PROMO123
Have you tried Routing?
Such as
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Don't forget to add this before default one.
routes.MapRoute(
name: "PromoRoute",
url: "{controller}/{myString}",
defaults: new { controller = "Promo", action = "Index", myString = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
You need to define a route pattern for this.
If you want this to work application wide, then you will need to change the default route. But I would suggest simply adding a specific route for this controller, in addition to the default route, because you probably don't want to override the default MVC routing for the whole app or you will lose the ability to use multiple actions per controller.
See your RouteConfig, try this route (MVC pre-5):
routes.MapRoute("myRoute", "PromoRoute/{id}",
new {controller="PromoRoute", action = "Index"});
With MVC5 you can add this directly to your action assuming you've enabled attribute routes:
[Route("PromoRoute/{id}")]
public ActionResult Index(string id) {
}

ASP.NET MVC 3 Routes Always Have Querystring Value "Area="

This is an annoyance that I've experienced for a long time, but now my client is asking me to address it.
In every route that gets generated (by a non-Default route), a query string value gets appended: "Area="
As an example:
// RouteConfig.Register():
routes.MapRoute(
"ProfileDetails",
"{slug}",
new { controller = "Profile", action = "Details" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
To generate a URL to the BadgeController.Index action, the Default route will be applied and the result will be /Badge... and that's what is expected.
But to generate a URL to the ProfileController.Details(someUser) action, the ProfileDetails route will be applied and the result will be /someUser?Area= ... which will work, but the ?Area= is unnecessary and messy.
I have no areas in my project. How do I get rid of that Area= query string value? This happens with all of my routes that are not the predefined Default route, not just the "ProfileDetails" one in this example.
I've tried removing the AreaRegistration.RegisterAllAreas() from my Global.asax file, since I assume it's not required.

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.

How does MVC routing understands the URL?

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.

Adding a parameter to the URL in ASP MVC

I need to have a parameter as part of my ASP MVC URL before Controller and Action:
http://www.mydomain.com/company1/Home
or
http://www.mydomain.com/company1/Clients/Detail/1
(Ideally I would like to have this as a sub-domain like this: http://company1.mydomain.com/Clients/Detail/1 so any answers solving this one is also appreciated)
I call this parameter Account. I tried adding something like this to the routing map:
"{account}/{controller}/{action}/{id}" but it gives me a 404 error when trying something like http://www.mydomain.com/company1/Home
Here is the RegisterRoutes in Global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("TestRoute", "{account}/{controller}/{action}/{id}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
Is there anything special I have to do when organising my Views folder or Controller actions?
Your error sounds like you are not giving a default for action in your route defaults.

Resources