I implemented two languages to the Blazor Application, in which I have a CultureSelector (selecting languages) and a CultureController which sets the culture as a cookie. I also use IStringLocalizer with resource files to map each of these. This works, until my razor page called "DevicePage.razor" gets data through a stream that looks something like this:
stream = await StreamSubscriber<DeviceStateEntry>.CreateAsync(clusterClient, "facility", FacilityId, async (entry) => { if (entry.FacilityId == FacilityId) { await InvokeAsync(() => { if (!Devices.ContainsKey(entry.Id)) { return; } else { Devices[entry.Id].Entries.Add(entry); StateHasChanged(); } });Whenever the StateHasChanged() is run, it looks almost like the UI is flickering between the new language and to the default language (and sometimes straight to the key of the resource files used).
My CultureController:
[Route("[controller]/[action]")]public class CultureController : Controller{ public IActionResult Set(string culture, string redirectUri) { if (culture != null) { HttpContext.Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue( new RequestCulture(culture, culture))); } return LocalRedirect(redirectUri); }}CultureSelector:
<MudStack><MudSelect Value="selectedCulture" T="CultureInfo" ValueChanged="OnCultureChanged"><MudSelectItem T="CultureInfo" Value="supportedCultures[0]"><img src="https://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_the_United_Kingdom_%283-5%29.svg" height="14" class="mr-1" />English</MudSelectItem><MudSelectItem Value="supportedCultures[1]"><img src="https://upload.wikimedia.org/wikipedia/commons/d/d9/Flag_of_Norway.svg" height="14" class="mr-1" />Norsk</MudSelectItem></MudSelect></MudStack>@code { private CultureInfo selectedCulture = CultureInfo.CurrentCulture; private CultureInfo[] supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("nb-NO"), }; private async Task OnCultureChanged(CultureInfo newCulture) { if (CultureInfo.CurrentCulture != newCulture) { var uri = new Uri(Navigation.Uri) .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); var cultureEscaped = Uri.EscapeDataString(newCulture.Name); var uriEscaped = Uri.EscapeDataString(uri); Navigation.NavigateTo( $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}", forceLoad: true); } }}There are perhaps things I don't know which is probably obvious to how a StateHasChanged() should be used, but surely there are other steps I am missing or has gone over my head in how to prevent this from happening? Let me know if the information is lacking, and on what I can provide to help you understand the cause of the matter.
I've tried numerous things:
- Set CultureInfo.CurrentCulture on controller. - I was expecting it to be able to change the culture on runtime, since it kept returning en-GB, but as i read through the web, its not how it works.
- Set CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture - This actually solved the problem in a very bad way, as I understand it changes not just for the user but for everyone that accesses the page. And I could only call this through the setting method of the controller and the CultureSelector, and I had no idea how / where to access the cookie to then set the Culture if the website should suddenly restart.
I've tried other stuff too, but I felt like i never understood what I was truly doing to being able to properly explain it here.