.net-6.0blazor-webassemblyasp.net-core-localization

Blazor localization do not load resource translations


I have a .NET 6 Bloazor PWA application where i want to let the customer choose the language for the UI of the app. I have prepared resource .resx files and set the Default language in Program.cs and set the AddLocalization service, but when i chose the language from the combo element the localized text on the page do not change at all. Moreover i always see the 'keys' instead their corresponding strings in resurces file; it looks like the system do to find resource files at all. where am i wrong ?

I used:

(.csproj file)

  <PropertyGroup>
    <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
  </PropertyGroup>

(Program.cs):

builder.Services.AddLocalization(Options => Options.ResourcesPath= "ResourceFiles");
var host = builder.Build(); CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("it-IT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("it-IT");
await host.RunAsync();

then i defined the ResourceFiles directory

enter image description here

with inside Resource.resx , Resources.it.resx with two text records with (Resources.it.resx and Resources.resx)

Name="intro1" value="Benvenuto!"
Name="intro2" value="Grazie per utilizzare la nostra app" `

(Resources.en.resx)

Name="intro1" value="Welcome!"
Name="intro2" value="Thank you for using our app" `

and in addition an empty Resources class to collect resx files and assign later it to IStringLocalizer in the razor page

namespace BlazorAppPWAalone.ResourceFiles
{
    public class Resources
    {
    }
}

in my page:

@using System.Globalization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<Resources> Loc

<h1>Language change:</h1>
<select name="lingue" id="idlingua" @bind="sceltaLingua">
  <option value="it-IT">Italiano</option>
  <option value="en-US">Inglese</option>
</select>

<p>
    <b>CurrentCulture</b>: @CultureInfo.CurrentCulture
    <b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture
</p>
<p>@Loc["intro1"], @Loc["intro2"]</p>


@code {
    private string _sceltaLingua;
    public string sceltaLingua
    { 
        get 
        {
            return _sceltaLingua;
        } 
        set 
        {
            _sceltaLingua = value;
            CambiaLingua(_sceltaLingua);
        } 
    }

    private void CambiaLingua(string newlang)
    {
        System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(newlang);
        System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(newlang);
        StateHasChanged();
    }
}

When i choose the language the @CurrentCulture and @CurrentUICulture variables show correctly the selected language but @Loc["intro1"], @Loc["intro2"] never change, it always displays default (italian) resource values.

Why ? where is my code 'bug' ?


Solution

  • I´ve not done this in WASM yet but in the documentation the CultureSelector does not actually set CurrentCulture to change the language but sets a key value pair in the browsers local storage and triggers a reload which causes DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture to be set to the culture specified in local storage.

    And judging from this:

    Always set DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture to the same culture in order to use IStringLocalizer and IStringLocalizer.

    just setting CurrentCulture and CurrentUICulture will probably not work.

    I don´t know if you can just set DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture from the component and reload or if you need to follow the documentations exact approach but that should be easy for you to try out.