0

I need a help to select language and change the CultureInfo dynamically after selecting the desired language. I have the files .resx , the view and the controller. But I use Tenant, so.. It is possible or recommended change the language in it?

I have in view:

<div class="form-group" >
  <select id="idiomSelect"  class="form-control" style=" border-color: #FFFFFF;">
    <option id="pt-BR" ng-selected="selected">Português (Brasil)</option>
    <option id="es-CL">Español (Chile)</option>
    <option id="es-ES">Español (España)</option>
    <option id="en-US">English (USA)</option>
   </select>
</div>

And I thought of building a method with the following parameters(example with en-US):

Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
 Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");

Could anyone help me, please?

Eduardo Andrade
  • 216
  • 4
  • 12

2 Answers2

1

Dealing with multi-tenancy (i.e. multiple domains mapping to the same application). The answer for this does depend on how the tenencies are set up. For example, if you follow the Wikipedia model, the culture name is encoded in the URL (i.e. en.wikipedia.org, ja.wikipedia.org, de.wikipedia.org). In this case you have your CultureInfo encoded into the URL itself. You just need to extract it and use it to retrieve your resource. If you have another model for multi-tenancy, then your best bet might be to use a session variable or cookie to remember the requested culture.

The remaining part of the problem is directly related to i18n (internationalization) and l10n (localization). The folks at ASP.Net have come up with a great article on how to build that infrastructure in to your system (link to article). Essentially it uses the some of the clues I provided, but wraps them up in helper classes so you always have access to it as you need it:

  • They recommend using the ASPNET_CULTURE cookie (CookieRequestCultureProvider) to store the culture info.
  • The preferred option to automatically detecting the desired culture is to use the Accept-Language HTTP header. When set, it provides the preferred order of cultures. This provides a better experience for expats who live in foreign countries but want to read in their native language.
  • Your .resx files follow the standard naming pattern: (FileName.resx for default language, FileName.fr.resx for the French culture, etc.). The i18n variants must live in the same namespace/folder as the default .resx file. (this is required for the ResourceManager to resolve resources based on culture info).
  • The article provides examples of creating your own helpers to look up and resolve resources automatically.

The ".resx" file has a few properties and methods that you may not know about.

  • Culture -- the CultureInfo to use for all requests by name
  • ResourceManager -- the actual dictionary for the resources

Each property you've defined in your ".resx" file simply calls the following equivalent method:

ResourceManager.GetString("ResourceName", Culture);

There's nothing that automatically looks at your Thread.CurrentCulture values automatically. However, you can use the nameof() operator and that value to get your values:

MyResources.ResourceManager.GetString(
    nameof(MyResources.ResourceManager.ResourceName),
    Thread.CurrentUICulture);
Berin Loritsch
  • 11,400
  • 4
  • 30
  • 57
  • Thank you @Berin Loritsch. I can catch the language and pass it by the thread, but does not change the language on the page. After get the CultureInfo with the Thread, I tried: return View(); But is not work..It didn't change the language. And the Tenant is multi-tenancy.. I have a class to check subdomain and it is called every time we open a page. – Eduardo Andrade May 25 '16 at 13:29
  • I get language by jquery on the view via post .. just like : $.post('../Autenticacao/VerificarIdioma', { idiomaString: this.value }) – Eduardo Andrade May 25 '16 at 14:03
  • I've updated my answer, please make sure your ".resx" files and the international variants are in the same directory. It seems that this is primarily an i18n/l10n question and multi-tenancy is just another (possibly unrelated) wrinkle. NOTE: if your cookies are too specific in scope (i.e. for only one tenant) then they won't be supplied automatically to other tenants. – Berin Loritsch May 25 '16 at 15:31
0

Thank you guys .. I got it..

    OutputCache(NoStore = true, Duration = 0)]
    // set language on select(view) and create a cookie  
    [HttpGet]
    public ActionResult SetCulture(string idiomString)
    {

        HttpCookie cookie = Request.Cookies["_culture"];
        if (cookie != null)
            cookie.Value = idiomString;   
        else
        {
            cookie = new HttpCookie("_culture");
            cookie.Value = idiomString;
        }
        Response.Cookies.Add(cookie); 

        return RedirectToAction("Index");
    }

    // set the language 
     protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) 
    {

        string cultureName = null;

        HttpCookie cultureCookie = Request.Cookies["_culture"];

        if (cultureCookie != null)
            cultureName = cultureCookie.Value;
        else
            cultureName = Request.UserLanguages["0"]; 

        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

        return base.BeginExecuteCore(callback, state);
    }
Eduardo Andrade
  • 216
  • 4
  • 12