I'm trying to create URIs that look a little something like this:
http://hostname/mobile/en/controller/action
for mobiles OR http://hostname/en/controller/action
for desktop (non mobiles).
My Route table currently looks like this (Global.asax.cs)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Mobile", // Route name
"mobile/{language}/{controller}/{action}/{id}", // URL with parameters
new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
routes.MapRoute(
"Default", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
The problem occurs when I try to do a
return RedirectToAction("Add", "User");
It always redirects the desktop browser from /en/User/List
to /mobile/en/User/Add
when I want it to go to /en/User/Add
.
The Mobile version works correctly but I believe this is because the first "Mobile" route is always been seen to be the route that matches even if it doesn't have /mobile/ at the start.
I'm trying to use the same Controller for both versions but am stuck at it always redirecting to the Mobile route. This means RedirectToRoute
isn't prefect as I want dynamic routes.
Thanks for your help.
The main issue is that the route-values you provide match both routes, which means it will take the first one (which is mobile).
You can manually select which route to use by redirecting to routes in stead of actions.
return RedirectToRoute("Mobile", new {
language = "en", controller = "User", action = "Get", id = 20
});
for mobile or
return RedirectToRoute("Default", new {
language = "en", controller = "User", action = "Get", id = 20
});
for your default route.
However, this leaves you with a new problem: obtaining the name of the current route. As seen in the example, referring to named routes is very well possible. Obtaining the name of the currently used route however seems to be impossible. Using a hack like looking at the current URI is obviously not desireable. Besides being ugly (a hack) it could also lead to a lot of code duplication.
There is however a possibility of adding values to the routes which can be easily obtained from your controller (or view):
routes.MapRoute(
"Mobile", // Route name
"mobile/{language}/{controller}/{action}/{id}", // URL with parameters
new { routeName = "Mobile", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
routes.MapRoute(
"Default", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { routeName = "Default", language = "en", controller = "Route", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = @"en|us" } // validation
);
Now from your code you can redirect to the current route by using the value provided from the route itself:
return RedirectToRoute(RouteData.Values["routeName"], new {
language = "en", controller = "User", action = "Get", id = 20
});
Now if you want to make this completely fancy, you can even make an extension method out of this:
public static class ControllerExtensions {
public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, object routevalues) {
return CustomRedirectToRoute(controller, controllerName, actionName, new RouteValueDictionary(routevalues));
}
public static RedirectToRouteResult CustomRedirectToRoute(this Controller controller, string controllerName, string actionName, RouteValueDictionary routevalues) {
routevalues = routevalues ?? new RouteValueDictionary();
routevalues.Add("controller", controllerName);
routevalues.Add("action", actionName);
return new RedirectToRouteResult(controller.RouteData.Values["routeName"] as string, routevalues);
}
}
Hopefully this provides a nice solution to your problem!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With