Reputation: 1199
I'm having a problem trying to get routing to work with ASP.NET MVC 3.0. I have the following routes declared:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional }
);
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
);
routes.MapRoute(
"TestRoute2",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
When I visit:
http://localhost
The site works correctly, and it appears to hit Default
route.
When I visit:
http://localhost/1
I get a 404:
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.
Requested URL: /1
Here are the actions those routes correspond to:
public ActionResult Index3(int? id)
{
Product myProduct = new Product
{
ProductID = 1,
Name = "Product 1 - Index 3",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
Product myProduct2 = new Product
{
ProductID = 2,
Name = "Product 2 - Index 3",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
ViewBag.ProcessingTime = DateTime.Now.ToShortTimeString();
if (id == 1)
return View("index", myProduct);
else
return View("index", myProduct2);
}
How do I structure my routes so that all three action methods are hit correctly?
Upvotes: 14
Views: 19265
Reputation: 3661
In my case, the answer for the same problem was a matter of needing to "include in project" the relevant controllers and views instead of incorrect routing rules.
When mine were created, they weren't automatically included for some reason. This problem was revealed after I closed and re-opened the solution.
{+1 hate} awarded to Visual Studio for its faulty hyper-automation sending me digging through Web.Config files, trying to tack on extensions, and even trying (and failing) to whip up a decent ErrorController.
Upvotes: 0
Reputation: 835
Your routes MapRoute Default should be the last.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional }
);
Upvotes: 2
Reputation: 57877
ASP.NET MVC Routing evaluates routes from top to bottom. So if two routes match, the first one it hits (the one closer to the 'top' of the RegisterRoutes
method) will take precedence over the subsequent one.
With that in mind, you need to do two things to fix your problem:
What's the difference between:
example.com/1
and
example.com/index
To the parser, they contain the same number of segments, and there's no differentiator, so it's going to hit the first route in the list that matches.
To fix that, you should make sure the routes that use ProductIds
take constraints:
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional },
new { id = @"\d+" } //one or more digits only, no alphabetical characters
);
There are other issues with your set up, but those are two things that come to mind right off the bat.
Upvotes: 12
Reputation: 14944
Move your Default route to the end, Default route should be the last route to define because it acts as a catch all route
Upvotes: 0
Reputation: 82903
Push the most generic route to the last of the MapRoute call chain.
Try this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional } // Parameter defaults
//new { controller = "Product", action = "Index2", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"TestRoute2",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Upvotes: 0