1

I'm developing an app with blazor server side net 6. the purpose is to have the possibility to select the preferred language for each user.

The problem is that when a user changes the language, it changes for all users

I added this line in the program.cs Program.cs

builder.Services.AddLocalization();

I created a dropdown menu where the user selects the desired language

  <MudSelect 
Class="mud-select text-field label-background-transparent pb-6 mr-3"
@bind-Value="_currentCultureOramsWeb" 
T="string" 
AnchorOrigin="Origin.BottomCenter" 
SelectedValuesChanged="ChangeSelectedCurrentCulture" 
Style="max-width:50px;" 
Edge="Edge.End">
                    
@foreach (var culture in oramsCultureInfosWeb)
    {
     <MudSelectItem Value="@culture" />
    }

</MudSelect>

once the user changes the language, i intercept the event and I change the cultureinfo

  _currentCultureOramsWeb = ci.OramsCultureInfoKey
  // ci.OramsCultureInfoValue is a string like en-US, de-DE
  CultureInfo cultureInfo = new CultureInfo(ci.OramsCultureInfoValue);
  CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
  CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

Other than that, there are also all the .resx files once the language has been changed, I save the information in the database, linked to the user, so that this is called every time he accesses to the app

Update

In the MainLayout.razor.cs I inctercept the chenge

this is the function

        async void ChangeSelectedCurrentCulture(IEnumerable<string> values)
        {
            string newSelected = values.First();
            var ci = (from cii in oramsCultureInfoList
                      where cii.OramsCultureInfoKey == newSelected
                      select cii).First();

            _currentCultureOramsWeb = ci.OramsCultureInfoKey;

            //ci.OramsCultureInfoValue is a string 
            CultureInfo cultureInfo = new CultureInfo(ci.OramsCultureInfoValue);
            //CurrentCulture = cultureInfo;

            CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
            CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

            if (Username != null)
            {
                using (UintOfWork uow = new UintOfWork())
                {
                    bool ris = await uow.OramsUserRepository.UpdateCultureInfoForUser(Username, ci.OramsCultureInfoKey);
                    if (ris)
                    {
                        await uow.CompleteAsync();
                    }
                }
            }

            StateHasChanged();
            if (MainJS != null)
            {
                // Refresh all with JS
                await MainJS.InvokeVoidAsync("ReloadPageAfterLangChange");
            }
        }

And this is the file Program.cs, for the localization I added only one line (builder.Services.AddLocalization();)

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using ORAMS_III_Blazor_server.Data;
using MudBlazor.Services;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using ORAMS_III_Blazor_server.Authentication;
using Serilog;
using Microsoft.Extensions.DependencyInjection;
using ORAMS_III_Blazor_server.Logger;
using ORAMS_III_Blazor_server.PageSupport;
using ORAMS_III_Blazor_server.Data.Dashboard;
using ORAMS_III_Blazor_server.Data.Logger;

/**
* @author Niki Gagliardi
*
* @date - 12/1/2022 3:42:05 PM
*
* @version - 1.0
*/




var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();




// Per info seguire i seguenti link
//https://learn.microsoft.com/it-it/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-3.1#reflect-the-connection-state-in-the-ui
//https://learn.microsoft.com/it-it/aspnet/core/signalr/configuration?view=aspnetcore-6.0&tabs=dotnet#configure-server-options
builder.Services.AddServerSideBlazor()
    .AddHubOptions(options =>
    {
        options.ClientTimeoutInterval = TimeSpan.FromSeconds(60*4);
        options.EnableDetailedErrors = false;
        options.HandshakeTimeout = TimeSpan.FromSeconds(1);
        options.KeepAliveInterval = TimeSpan.FromSeconds(1);
        options.MaximumParallelInvocationsPerClient = 1;
        options.MaximumReceiveMessageSize = 32 * 1024;
        options.StreamBufferCapacity = 10;
    });
//ex code
////builder.Services.AddServerSideBlazor();

//Multi-lang
builder.Services.AddLocalization();

// Add protected session
builder.Services.AddScoped<ProtectedSessionStorage>();

//Add CustomAuth
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>();

builder.Services.AddSingleton<WeatherForecastService>();

// Service Dashboard
builder.Services.AddSingleton<DashboardModelView>();

builder.Services.AddSingleton<PageSupportModel>();

//service Logger configuration page 

builder.Services.AddSingleton<LoggerConfigurationModelView>();

//httpcontext to get ip client in login page
builder.Services.AddHttpContextAccessor();


//var logger = new LoggerConfiguration()
//  .ReadFrom.Configuration(builder.Configuration)
//  .Enrich.FromLogContext();


#region OramsLogger
//read section SerilogUser from appsettings.json
var serilogUserInfo = builder.Configuration.GetSection("SerilogUser").Get<SerilogUser>();

// pass var to constructor of OramsLogger to create a dependency injection
builder.Services.AddSingleton<IOramsLoggerService>(s => new OramsLoggerService(serilogUserInfo));
#endregion


builder.Services.AddMudServices();

//Log.Logger = new LoggerConfiguration().CreateBootstrapLogger();
builder.Host.UseSerilog(((ctx, lc) => lc.ReadFrom.Configuration(ctx.Configuration)));


var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}
app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.UseSerilogRequestLogging();

app.Run();


UPDATE 2

I tried to change the code in this way.

MainLayout.razor.cs

        public CultureInfo CurrentCulture
        {
            get => _currentCulture;
            set
            {
                
                CultureInfo.CurrentCulture.ClearCachedData();
                _currentCulture = value;
                CultureInfo.CurrentCulture = value;
                CultureInfo.CurrentUICulture = value;
                //CultureInfo.DefaultThreadCurrentCulture = value;
                //CultureInfo.DefaultThreadCurrentUICulture = value;
            }
        }

        private CultureInfo _currentCulture;

When I intercet the change of language, I set the CurrentCulture variable.

In this way, I noticed that in the mainlayout component, the value is updated, but in the other components it remains the same.

  • 1
    ` i intercept the event and I change the cultureinfo` Could you tell me where do you change the cultureinfo please? – Arani Jan 25 '23 at 07:19
  • Sure. Inside MainLayout.razor.cs.I edited the post. – Niki Gagliardi Jan 25 '23 at 07:22
  • 1
    Thanks. Could you put the service register here please?(startup.cs or program.cs, e.g. services.AddSingelton...) – Arani Jan 25 '23 at 07:25
  • I did, in the file Programs.cs I added only one line for this scope – Niki Gagliardi Jan 25 '23 at 07:28
  • 2
    It seems that the problem is in registering singleton services. Please try this: register related services as scope such as: builder.Services.AddScope(); builder.Services.AddScope(); – Arani Jan 25 '23 at 07:42
  • I modified all services with addScoped, but the problem remains. I have two users in database (niki and niki2) when I change the language of niki and then refresh the page of the niki2 , the system changes language also for niki2 – Niki Gagliardi Jan 25 '23 at 07:59
  • these 2 lines of code (CultureInfo.DefaultThreadCurrentCulture = cultureInfo; CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; ) does it change the entire application or just the user's info culture? – Niki Gagliardi Jan 25 '23 at 08:00
  • I'm not sure, However, I provide some useful links. I hope that help you. https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-7.0&pivots=server#dynamically-set-the-culture-by-user-preference. and https://stackoverflow.com/a/61133286/4444757 – Arani Jan 25 '23 at 08:25

0 Answers0