Why is this MVC route incorrect? - asp.net-mvc

In my MVC application's RouteConfig I am using this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute (
name: "Dictionary", // Route name
url: "dictionary/{id}", // URL with parameters
defaults: new { controller = "Dictionary", action = "details" } // Defaults
);
At this time this URL succeeds in returning a page:
http://127.0.0.1:8080/dictionary/details/1
Whereas this fails:
http://127.0.0.1:8080/dictionary/1
With the exception
"HTTP 404.The resource you are looking for (or one of its dependencies) could have been removed, had its name changed..."
When I swap the routing around, like this:
routes.MapRoute (
name: "Dictionary", // Route name
url: "dictionary/{id}", // URL with parameters
defaults: new { controller = "Dictionary", action = "details" } // Defaults
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
It both URLs start returning a page.
Why is this?
Thanks in advance.
FYI This question is different to the possible duplicate because of the UrlParameter.Optional and the wild carded routing in the other question. This question is more about which specific ordering is correct and why.

The order of the routes that you add to the route table is important. If you reversed the order, then the Default route always will get called instead of the custom route.
Reference:
https://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-custom-routes-cs

Related

Asp.net mvc routing without a controller or action name

I am trying to redirect all urls that don't match an existing controller to a certain controller.
For example, the url mywebsite.com/newyork should be processed as mywebsite.com/Cities/Info/newyork
I am using the following code in my RegisterRoutes but it doesn't seem to work as I get a 404 reponse:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Cities",
url: "{cityname}",
defaults: new { controller = "Cities", action = "Info", cityname= "" }
);
You should put your cities route first and drop the empty default parameter:
routes.MapRoute(
name: "Cities",
url: "{cityname}",
defaults: new { controller = "Cities", action = "Info" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The routes are processed in order so you should have most specific first to least specific ( your default route).
As your website.com/newyork matched the default route, it wasn't continuing to your city route.

ASP.NET MVC routing to action

I'm having trouble doing what I want to achieve when doing routing in ASP.NET MVC.
What I want to do is the following:
When typing http://localhost/MyWebsite/, I want to redirect to http://localhost/MyWebsite/Login/ (The redirection to the action Index is implied here)
When typing http://localhost/MyWebsite/MyAction, I want to redirect to http://localhost/MyWebsite/Login/MyAction
Point 1 was achieved using the following lines in the file RouteConfig.cs:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional });
But I cannot accomplish point 2. Note that the user does not come from another action in a controller, but actually types the address in his browser.
Thanks for your help.
since /MyWebsite/Login and /MyWebsite/MyAction both have two segments in the URL, they're both matching your defined Route.
You can use a Route Constraint to only match /MyWebsite/Login to your first point, followed by a modified second route mapping:
routes.MapRoute(
name: "Default",
url: "MyWebsite/Login/",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
name: "Actions",
url: "MyWebsite/{action}/",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional });

URL not getting read correctly by MVC 4 routing

Hi I have a URL as follows in my MVC 4 application
http://localhost/ABC/Home/DeleteApp/3000
and I have configured RouteConfig.cs as follows
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
It goes to the Correct DeleteApp Controller but with the ID value Null. It shows the correct URL when I enable firebug.
What could possibly go wrong?
it debugs and come to here but the id field as null;
public void DeleteApp(string id)
{
try
{
// delete logic
}
catch (Exception e)
{
//
}
}
Possibles causes :
-> Check your "id" variable name (must be exactly the same name in the RouteConfig and in the controller action, it is case sensitive)
-> You have other routes mapped before this one that match the pattern
If you have a route mapped as {controller}/{action}/{something} and another route mapped as {controller}/{action}/{something_else}, when you call the url "Home/DeleteApp/3000", it can't tell if 3000 is "something" or "something_else" so it will take the first match.
To make this working, you have to use "Route Constraints"
http://www.codeproject.com/Articles/641783/Customizing-Routes-in-ASP-NET-MVC
You need to do it like so:
routes.MapRoute(
name: "ABC",
url: "ABC/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
If you want to have url in this format http://localhost/ABC then you will have to modify the route as below by adding ABC to {controller}/{action}/{id} expression.
routes.MapRoute(
name: "Default",
url: "ABC/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

MVC: Multiple Routes for 1 Controller

I want users to be able to access the "/Linecard" page of my ASP.Net MVC site using "/Linecard" or "/Manufacturers" as the URL... so same controller, 2 different possible URLs.
I tried adding the following:
routes.MapRoute(
name: "Manufacturers",
url: "Manufacturers/{action}/{id}",
defaults: new { controller = "Linecard", action = "Index", id = UrlParameter.Optional }
);
Adding this after the "Default" route doesn't work at all and I get a 404 error when I go to "/Manufacturers". Putting it BEFORE "Default" works, but then only "/Manufacturers" shows up in the URL when I click menu links since it is the first match. I would like "/Linecard" to always show as the URL.
Any pointers? Is there a certain constraint I can use to accomplish this? Thanks!
I had the same problem when we moved to extension-less URLs. We needed to continue to support one route with extensions. I got around it by having my default route apply to everything except the old URL, then after that mapping one specifically for the exception
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
// if controller specified does not match 'manufacturers' (case insensitive)
new { controller = "^((?i)(?!manufacturers).)*$" },
new string[] { "Namespace.Of.Controllers" }
);
routes.MapRoute(
"Manufacturers", // Route name
"Manufacturers/{action}/{id}", // URL with parameters
new { controller = "Linecard", action = "Index", id = UrlParameter.Optional },
new string[] { "Namespace.Of.Controllers" }
);
You could also set an order when mapping your routes with the defaults at the end like so
routes.MapRoute(
name: "Manufacturers",
url: "Manufacturers/{action}/{id}",
defaults: new { controller = "Linecard", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

How do I route all but only one controller to the 'Start' action, and routes for all other controllers to 'Index'?

My main starting page is ApplicantProfile, so my default route looks like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ApplicantProfile", action = "Start", id = UrlParameter.Optional }
);
This controller has no index for public access, but all others do. What I would like is the wildcard equivalent, e.g.
routes.MapRoute(
name: "Others",
url: "{controller}/{action}/{id}",
defaults: new { controller = "*", action = "Start", id = UrlParameter.Optional }
);
How can I achieve this?
This should take care of it:
routes.MapRoute(
name: "Default",
url: "ApplicantProfile/{action}/{id}",
defaults: new { controller = "ApplicantProfile", action = "Start", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
Assuming you have ApplicantProfileController, HomeController and OtherController, this will result in:
/ApplicantProfile → ApplicantProfileController.Start
/Other → OtherController.Index
/SomeOtherPath → default 404 error page
/ → default 404 error page
See http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/asp-net-mvc-routing-overview-cs for an introduction to routing. It's a bit old, but it covers the basics well.
Routing happens top-down, meaning it stops at the first match in the routing table. In the first case, you will match your ApplicantProfile route first, so that controller is used. The second case gets Other from the path, finds a matching controller and uses that. The last 2 do not find a matching controller and there is no default specified so a default 404 error is returned. I'd suggest putting in a proper handler for errors. See the answers here and here.
This should work as per your requirement
routes.MapRoute(
name: "ApplicantProfile",
url: "ApplicantProfile/Start/{id}",
defaults: new { controller = "ApplicantProfile", action = "Start", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
First one is url which will route you to "Start' Action, other one is default replace "Home" controller with your default one
The default should goto profile controller with start action and all the other request should land to index action what ever the controller.
Use the IRouteConstraint to add the constraint to the URL for Other Routes and place that above the default controller with the constraint on the Route for the controller.
You can add a check if the controller is not ApplicationProfile use it.
I hope this helps.

Resources