this seems like any other question about culture or routing, but I can't figure out why this is happening.
When I try to access an [Authorize]
element without being authenticated, I'm redirected to login page with a ReturnUrl param in query string. That's perfect. (boilerplate app)
Now my problem is: if I do the same with localisation within url (from routeConfig) ie: url: "{lang}/{controller}/{action}"
, I'm being redirected a first time with this parameter, but after been passed by the base controller that redirect me to a localized route. After that, ReturnUrl is null while login page (.cshtml) is loaded...
I've loooked into lots of articles, and tried numerous tricks/options and maybe on the way I did something that's breaks everything, so here are some code:
First RouteConfig :
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "LocalizedDefault",
url: "{lang}/{controller}/{action}",
defaults: new { lang = UrlParameter.Optional, controller = "Home", action = "Index" } ,
constraints: new { lang = "fr-CA|en-US" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
In BaseController:
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
string cultureName = RouteData.Values["lang"] as string;
// Attempt to read the culture cookie from Request
if (cultureName == null)
{
cultureName = Request.UserLanguages != null &&
Request.UserLanguages.Length > 0 ?
Request.UserLanguages[0] :
null; // obtain it from HTTP header AcceptLanguages
}
// Validate culture name
cultureName = CultureHelper.GetImplementedCulture(StartupMVC.SupportedLangs, cultureName);
if (RouteData.Values["lang"] as string != cultureName)
{
// Force a valid culture in the URL
RouteData.Values["lang"] = cultureName.ToLowerInvariant(); // lower case too
// Redirect user
//Response.SuppressFormsAuthenticationRedirect = false;
****HERE**** if I comment this line, I keep returnUrl but my route is like {controller}/{action}/{id} => So default language Response.RedirectToRoute(RouteData.Values); otherwise route ok {lang}/{controller}/{action}/{id} but no ReturnUrl
}
SetCurrentCultureOnThread(cultureName);
return base.BeginExecuteCore(callback, state);
}
and a bit of Login.cshtml:
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
...
}
I hope this is silly and there is some obvious solution you could point out to me. Otherwise, does anyone understand this? and maybe help me to fix it?
PS : if I not being clear enough or you need some more info, please comment what you need! :)
Edit : from NightOwl888's comment, I'd like to add some more questions:
_I kwow there is at least 3 major ways of handling localization (locale in query string, in route, translating the url), but is there any documented or commonly used Best Practices regarding localization and culture?
_How does the .NET framework handles the redirect to login and how does it handles the query string? (since we can not register route with query string values)
Added QueryStrings to end of Routes: