Ryan M
Ryan M

Reputation: 605

asp mvc RedirectToRoute adding current action to the redirect

I have a controller that has an action called RedirectLogin, it basically sets a TempData var to redirect back to when the login is finished.

After this, it simply calls:

return RedirectToRoute("Login");

However, the when it redirects, it goes to /login/RedirectLogin - it is tacking on the calling action's name for some reason. I think it should just be returning the defaults, not adding actions, especially actions not part of the destination controller.

If I call:

return RedirectToRoute("Login", new { action = "Index" });

Then it properly makes the path /login, but again, shouldnt it be doing that by default, without the extra bit?

I have a slightly non-standard routing setup. Basically I am creating virtual subfolders for my clients, so www.domain.com/clienturl but I still want www.domain.com/join or www.domain.com/about to redirect to non-client data. I do this by adding the name of the controller directly in the path, and add it before the more generic one called Landing. Could this be the problem, or is there a better way to do it :)

        // Root paths
        routes.MapRoute("About", "about", new { controller = "Home", action = "About" });
        routes.MapRoute("Info", "info", new { controller = "Home", action = "Info" });
        routes.MapRoute("Privacy", "privacy", new { controller = "Home", action = "Privacy" });
        routes.MapRoute("Terms", "terms", new { controller = "Home", action = "Terms" });

        // Root controllers
        routes.MapRoute("Join", "join/{action}/{id}", new { controller = "join", action = "Index", id = UrlParameter.Optional });
        routes.MapRoute("Login", "login/{action}/{id}", new { controller = "login", action = "Index", id = UrlParameter.Optional });
        routes.MapRoute("Account", "account/{action}/{id}", new { controller = "account", action = "Index", id = UrlParameter.Optional });
        routes.MapRoute("Goodbye", "goodbye/{action}/{id}", new { controller = "goodbye", action = "Index", id = UrlParameter.Optional });

        // Organization
        routes.MapRoute("Landing", "{organization}/{controller}/{action}/{id}", new { controller = "Landing", action = "Index", id = UrlParameter.Optional });

        // Default
        routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Upvotes: 0

Views: 4199

Answers (2)

maciek
maciek

Reputation: 661

It's reusing the data from the current request. since you have the optional parameter 'action' it is taking the action parameter from your current request who's action is RedirectLogin and it attaches that to the url. I'd make a specific route entry without the optional parameters to your login page or redirect to action and not used named routes. There is a page in the book Pro ASP.NET MVC 2 that explains what's happening in more detail.

Upvotes: 2

Ron DeFreitas
Ron DeFreitas

Reputation: 657

Alternatives you may wish to try are as follows:

RedirectToAction(String, String, RouteValueDictionary);
RedirectToAction(String, RouteValueDictionary);
Redirect("~/login"); // Note, this works but if you move around the urls for your routes you'll need to fix it everytime... not recommended

The MSDN article here shows all of the available Methods on a Controller: http://msdn.microsoft.com/en-us/library/system.web.mvc.controller_methods%28v=VS.98%29.aspx

Don't use the RedirectToActionPermanent or RedirectToRoutePermanent for this purpose though...

Upvotes: 1

Related Questions