12

I have a curiosity related to culture change in MVC. I tried in 2 ways, but apparently I was wrong somewhere.

In my Web.config I have :

 <globalization uiCulture="auto" culture="auto" />

This is how I tried to change the thread culture :

 <li>@Html.ActionLink("Eng", "ChangeCulture", "Home", new { lang="en-US"}, new { @class = "languageSelectorEnglish" })</li>

First method

I have the following controller :

    public void ChangeCulture(string lang)
    {
        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(lang);
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);

        Response.Cookies.Remove("Language");
        var langCookie = new HttpCookie("Language");
        langCookie["Language"] = lang;
        langCookie.Value = lang;
        langCookie.Expires = System.DateTime.Now.AddDays(21);
        Response.Cookies.Add(langCookie);

        Response.Redirect(Request.UrlReferrer.ToString());
    }

Second method

    public ActionResult ChangeCulture(string lang)
    {
        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(lang);
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang);

        // Split the url to url + query string
        var fullUrl= Request.UrlReferrer.ToString();
        var questionMarkIndex = fullUrl.IndexOf('?');
        string queryString = null;
        string url = fullUrl;
        if (questionMarkIndex != -1) // There is a QueryString
        {
            url = fullUrl.Substring(0, questionMarkIndex);
            queryString = fullUrl.Substring(questionMarkIndex + 1);
        }

        // Arranges
        var request = new HttpRequest(null, url, queryString);
        var response = new HttpResponse(new StringWriter());
        var httpContext = new HttpContext(request, response);

        var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));

        // Extract the data    
        var values = routeData.Values;
        var controllerName = values["controller"];
        var actionName = values["action"];
        var areaName = values["area"];

        return RedirectToAction(actionName.ToString());
    }

Where am I wrong ? Thank you.

Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
Cosmin
  • 2,184
  • 21
  • 38

2 Answers2

8

It's seems I need to override the culture for my resource strings and not the thread. So my final method is this :

    public void ChangeCulture(string lang)
    {
         Resources.Resources.Culture = new CultureInfo(lang);

         Response.Redirect(Request.UrlReferrer.ToString());
    }

Hope this helps.

UPDATE :

The code above is not good when your application is used by multiple users, because it sets same culture for every user, no matter what browser they are using.

The good way to do it is to make a method which sets a cookie in your browser :

    public void ChangeCulture(string lang)
    {
        Response.Cookies.Remove("Language");

        HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["Language"];

        if (languageCookie == null) languageCookie = new HttpCookie("Language");

        languageCookie.Value = lang;

        languageCookie.Expires = DateTime.Now.AddDays(10);

        Response.SetCookie(languageCookie);

        Response.Redirect(Request.UrlReferrer.ToString());
    }

After this ( the tricky way ) you need to make every controller to inherit from one BaseController. It is tricky because you need to override Initialize.

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {


        HttpCookie languageCookie = System.Web.HttpContext.Current.Request.Cookies["Language"];
        if (languageCookie != null)
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo(languageCookie.Value);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageCookie.Value);
        }
        else
        {
        //other code here
        }


        base.Initialize(requestContext);
    }
Community
  • 1
  • 1
Cosmin
  • 2,184
  • 21
  • 38
4

Remove the line in your web.config:

<globalization uiCulture="auto" culture="auto" />

Setting these to auto will default the language to the user's language set on the browser. This is overriding your Thread setting.

Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
  • Hello. It didn't work, but I found a way to do it. I'll post my answer as soon as I can. Thank you very much . – Cosmin Feb 27 '13 at 10:15
  • In my case, just by having the line in the config file regardless of culture setting already overrides the thread settings. – Ben Junior May 17 '19 at 20:37