I just updated my Asp.Net Mvc 2 project to Mvc 3 and suddenly my links stopped working. When I open a page, all links on the page redirect back to itself.
Also, some redirects to actions that used to work in the previous version don't working anymore. It keeps saying 'No route in the route table matches the supplied values.'. I used RouteDebug to see what was going on, but couldn't find any problems.
Update
Here's one of the routes i'm using:
// ** Standard route. **
context.MapRoute(
"group_default", // Route name
"{language}/{organisation}/Research.aspx/{controller}/{action}/{organisationId}/{parameter}/",
// URL with parameters
new
{
area = "research",
language = "en-US",
organisation = "",
controller = "Home",
action = "Index",
organisationId = UrlParameter.Optional,
parameter = UrlParameter.Optional
}, // Parameter defaults
new[] { "Project.Web.Areas.Research.Controllers" }
);
As you can see in my answer below, the problem was caused by two UrlParameter.Optional after each other. This is a bug in Mvc 3
Wow, after about 4 hours of debugging I found the problem: It's a bug in Mvc 3. Because of the bug, it's not possible to use two UrlParameter.Optional after each other. Phil Haack has a nice blog-post about it: http://haacked.com/archive/2011/02/20/routing-regression-with-two-consecutive-optional-url-parameters.aspx
Hope this will help others (and save them some time)
Related
I have been trying to solve this problem for a couple of days now with no success.
The case is i have rewritten an old web forms site to mvc 3 and have a bunch of legacy url:s that need to be redirected to new url:s
This is what the 2 routes look like in global.asax that should catch all requests to old url:s
routes.MapRoute(
"legacyevents",
"events/{*slug}",
new { controller = "Redirect", action = "RedirectLegacyRoute" },
new[] { "Web.Controllers" }
);
routes.MapRoute(
"legacyarticles",
"articles/{*slug}",
new { controller = "Redirect", action = "RedirectLegacyRoute" },
new[] { "Web.Controllers" }
);
The weird thing is now that when a request looks like this
events/randomevent__12.aspx
everything works well but if the E in events is upper case Events/randomevent__12.aspx
asp.net somewhere adds another events word to the url so it looks like this when it hits the RedirectController
events/events/randomevent__12.aspx
Due to lack of knowledge about SEO when i wrote the web forms app few years back alot of incoming links to the old urls have mixed casing :( so i really have to fix this issue
The route that should handle articles works as intended and does not care about the casing of the incoming request url which which makes this case so weird, since the routes are pointed to the same RedirectController.
Any help will be appreciated and if you need any additional info i will happily provide it
best regards
//K
You do know that you can use full power of regular expressions in your route matching?
See examples here.
I am building a simple web site for a client and this is my first time with ASP.Net Mvc.
For the production i need to use MVC 1.0 and the most efficient way to saparate Admin logic from the rest of this site is using Areas.
The fact that i couldnt use MVC 2, so i have used the Haacks area prototype and everything was ok.
I want to write a custom routing for paging results but i couldnt get it done.
routes.MapAreas("{controller}/{action}/{id}",
"Adore.Web",
new[] { "Admin" });
//my custom routing
routes.MapRoute(
"PagingServices",
"Admin/Services/{pageNumber}",
new { area = "Admin", controller = "Services", action = "Index" });
routes.MapRootArea("{controller}/{action}/{id}",
"Adore.Web",
new { controller = "Home", action = "Index", id = "" });
As you see above i am trying to get this "Admin/Services/1" but couldnt figure it out.
How can i do it, thanks in advance !
Have you tried Phil Haack's Routing Debugger? :) http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx
That might help.
Also, it looks like the problem might be that your first route is going to match anything starting with /Admin. Try moving your custom route to the top since routes are evaluated in order.
My first route:
// Should work for /Admin, /Admin/Index, /Admin/listArticles
routes.MapRoute(
"Admin", // Route name
"Admin/{action}", // URL with parameters
new { controller = "Admin", action = "Index" } // Parameter defaults
);
is not resolving the route(I use Phil Haack's Route Debugger) and even the last route, "Catch All" route does not work:
//Maps any completely invalid routes to ErrorController.NotFound
routes.MapRoute("Catch All", "{*path}",
new { controller = "Error", action = "NotFound" }
);
If I go to /Admin/listArticles it works but /Admin gives me Error 403.15 "The Web server is configured to not list the contents of this directory." That points me to the idea that no routing is used as it looks for a physical file in a directory?
This is a simple low-level route problem but I cannot get it to work and everybody gives me links to read (yes I know MSDN is out there) but no real answers. I have researched routes and have tried but I am posting this because I cannot get it to work, any help, answers?
The answer to my question was that I had a route called /Admin and I wrote my error log to a directory /Admin/Error It seems that there is no overload to specify if the route should be resolved or if it is part of a physical directory.
The problem might be that you have added this route below the default route, all custom routes should be added above default route.
Are you using IIS 6.0? If so it'll need to look like...
// Should work for /Admin, /Admin/Index, /Admin/listArticles
routes.MapRoute(
"Admin", // Route name
"Admin.mvc/{action}", // URL with parameters
new { controller = "Admin", action = "Index" } // Parameter defaults
);
Where you need to set mvc as an application extension
How do you set up the routing to handle http://mysite.com/Foo?
Where foo can be any value. I want it to go to /Home/Action/Id where foo is the id.
These are the mappings I have tried:
routes.MapRoute("Catchall", "{*catchall}",
new { controller = "Home", action = "Index", id=""});
routes.MapRoute("ByKey", "{id}",
new { controller = "Home", action = "Index" id=""});
They both generated a 404.
Thanks for any help.
Try this (note you had a missing comma in your original post):
routes.MapRoute("ByKey", "{id}",
new { controller = "Home", action = "Index", id=""});
I would, however, make it a bit more explanatory to prevent clashes later, even if it means a bit longer URIs:
routes.MapRoute("ByKey", "ByKey/{id}",
new { controller = "Home", action = "Index", id=""});
And place this as the first MapRoute command. Order does matter there, and the first route you add is the first route for a URL to be tested with.
Your second route is correct. It should work. Maybe you have another routes above? Debug your routes with Phil Haack's ASP.NET Routing Debugger
Steps to solve
Right click on the project
Go to web tab of the page.
My Start URL was found to be empty
I copied what in Project url of Servers section
Pasted at Start Url
It worked.
I know this site is written using ASP.Net MVC and I do not see "/Home" in the url. This proves to me that it can be done. What special route and do I need?
Just change "Home" to an empty string.
routes.MapRoute(
"Home",
"",
new { action = Index, controller = Home }
);
If you're running on IIS 7, you can simply delete the Default.aspx file that comes with ASP.NET MVC (assuming you're running on Preview 3 or higher). That file was needed due to an issue with Cassini that was fixed in .NET 3.5 SP1. For more details check out:
http://haacked.com/archive/2008/04/10/upcoming-changes-in-routing.aspx
and
http://haacked.com/archive/2008/05/12/sp1-beta-and-its-effect-on-mvc.aspx
I actually like having all of my home controller methods to be at the root of the site. Like this: /about, /contact, etc. I guess I'm picky. I use a simple route constraint to do it. Here is my blog post with a code sample.
I'd add
routes.MapRoute("NoIndex", "{action}", new { controller = "Home", action = "Index" });
in RouteConfig.cs
This is what I did to get rid of Home. It will treat all routes with only one specifier as Home/Action and any with two as Controller/Action. The downside is now controller has to have an explicit index (/Controller != /Controller/Index), but it might help you or others.
routes.MapRoute(
"Default",
"{action}",
new { controller = "Home", action = "Index" }
);
routes.MapRoute(
"Actions",
"{controller}/{action}",
new { }
);
In IIS 7, you can simply delete the Default.aspx file that comes with ASP.NET MVC (assuming you're running on Preview 3 or higher). That file was needed due to an issue with Cassini that was fixed in .NET 3.5 SP1.
For more details check out:
Upcoming Changes In Routing and .NET 3.5 SP1 Beta and Its Effect on MVC