I've looked at a lot of similar questions to this one but nothing has solved my issue. I persist my users language in a cookie. First, its an Umbraco site. I have a default controller that is hit for every request in order to check the language.
I do some calculations to check what language the user should be on in the controller and then set the cookie like below.
private void SetCulture(string language, bool updateCookie)
{
if (updateCookie)
{
var newCookie = new HttpCookie("currentLanguage", language) { Expires = DateTime.Now.AddDays(30) };
Response.Cookies.Add(newCookie);
Request.Cookies.Add(newCookie);
}
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
}
Currently I'm updating both the request and the response cookie. The issue is after I hit the controller, I load my view. In my view I use a helper to get the current cookies value, however the cookie in the request has not been updated and still holds its original value. So for example, say a user is on the EN page, they user a language switcher to change to FR, I update the cookie in the controller using the SetCulture
method above which works, but in my helper class, the cookie is still set to the original EN value. The CookieHelper
is below.
public static class CookieHelper
{
public static string GetLanguageCookie()
{
var newCookie = HttpContext.Current.Request.Cookies["currentLanguage"];
return newCookie?.Value ?? "en";
}
public static void UpdateLanguageCookie(string lang)
{
var newCookie = HttpContext.Current.Request.Cookies["currentLanguage"];
if (newCookie?.Value != null)
{
newCookie.Value = lang;
newCookie.Expires = DateTime.Now.AddDays(30);
}
else
{
CreateLanguageCookie(lang);
}
}
public static void CreateLanguageCookie(string lang)
{
var newCookie = new HttpCookie("currentLanguage", lang) { Expires = DateTime.Now.AddDays(30) };
HttpContext.Current.Response.Cookies.Add(newCookie);
}
}
The controller below has been cut down for just the question relevant code. Just to clarify, the website is broken up into regional sections, UK, FR, and DE. each region site has a set of allowed languages DE = "en,de" uk = "en" and fr = "fr". Strange set up I know, but I'm just following the spec. Hoping the explanation makes the code a bit clearer.
public class BaseRenderController : RenderMvcController
{
public override ActionResult Index(RenderModel model)
{
var language = Request.UserLanguages.First().ToLowerInvariant().Substring(0, 2);
// If true it means where on the language select screen.
if (Request.Url.Segments.Length == 1)
{
if (language == "en")
{
SetCulture("en", false);
}
else if (language == "fr")
{
SetCulture("fr", false);
}
else if (language == "de")
{
SetCulture("de", false);
}
else
{
SetCulture("en", false);
}
}
else
{
var currentLang = CookieHelper.GetLanguageCookie();
if (Helpers.UrlHelper.GetRegionalSegmentFromUrl().Substring(1).ToLower() == "uk")
{
SetCulture("en", true);
}
else if (Helpers.UrlHelper.GetRegionalSegmentFromUrl().Substring(1).ToLower() == "fr")
{
SetCulture("fr", true);
}
else if (Helpers.UrlHelper.GetRegionalSegmentFromUrl().Substring(1).ToLower() == "de")
{
if (language == "de" || currentLang == "de")
{
SetCulture("de", true);
}
else
{
SetCulture("en", true);
}
}
}
return base.Index(model);
}
private void SetCulture(string language, bool updateCookie)
{
if (updateCookie)
{
var newCookie = new HttpCookie("currentLanguage", language) { Expires = DateTime.Now.AddDays(30) };
Response.Cookies.Add(newCookie);
Request.Cookies.Add(newCookie);
}
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
}
}