Open joostvz opened 6 months ago
Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.
Author: | joostvz |
---|---|
Assignees: | - |
Labels: | `arch-wasm`, `untriaged`, `needs-area-label` |
Milestone: | - |
Tagging subscribers to this area: @dotnet/area-system-globalization See info in area-owners.md if you want to be subscribed.
Author: | joostvz |
---|---|
Assignees: | - |
Labels: | `arch-wasm`, `area-System.Globalization`, `untriaged`, `needs-area-label` |
Milestone: | - |
I think you could add this C# code to call the equivalent JS code. You have an example here.
[JSImport("INTERNAL.loadSatelliteAssemblies")]
internal static partial Task LoadSatelliteAssemblies(string[] culturesToLoad);
@dvoituron Thanks for your response. This is indeed what the Blazor.WebAssembly.DynamicCulture library is also doing, and this approach works.
My only concern is that this is using an internal Blazor API, with zero guarantees. Hence my feature request to open up this API in a decent way.
There isn't anything in the runtime that restricts which satellite assemblies can be loaded and if they are added to the correct items I believe the build will correctly pick them up but blazor has some custom logic here so @maraf can you take a look and give appropriate guidance.
Making a public C# API is on our radar, but so far you are the first one asking for it.
In the meantime there are several workarounds
a) Use JSImport as mentioned above (the drawback is that the API might change between major .NET versions)
b) Load all satellite assemblies Blazor.start({ configureRuntime: runtime => runtime.withConfig({ loadAllSatelliteResources: true }) })
(wich also uses internal switch)
c) If you know which assemblies contain resources, you fetch them from C#
var http = new HttpClient();
var dllBytes = await http.GetByteArrayAsync("/_framework/en-US/WasmBasicTestApp.resources.wasm");
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes));
I'm curious what is your motivation for switching between cultures without reload? In a typical scenario users do this once and then use the prefered culture.
Thanks for the provided workarounds @maraf. I will give them a try.
My scenario is the following: I'm developing a web app for a kiosk in a store. Users can select their preferred language on the screen. A page reload would probably cause a blinking page. Also, users should be able to switch the language at any moment in the process, even when they're filling in data in a form. A page reload would require all form data to be temporarily stored somewhere.
So for my scenario a page reload is possible, but has negative impact on the user experience, and adds technical challenges.
My scenario is the following
Thank you for sharing! It makes perfect sense for your scenario
Making a public C# API is on our radar, but so far you are the first one asking for it.
In the meantime there are several workarounds a) Use JSImport as mentioned above (the drawback is that the API might change between major .NET versions) b) Load all satellite assemblies
Blazor.start({ configureRuntime: runtime => runtime.withConfig({ loadAllSatelliteResources: true }) })
(wich also uses internal switch) c) If you know which assemblies contain resources, you fetch them from C#var http = new HttpClient(); var dllBytes = await http.GetByteArrayAsync("/_framework/en-US/WasmBasicTestApp.resources.wasm"); AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes));
I'm curious what is your motivation for switching between cultures without reload? In a typical scenario users do this once and then use the prefered culture.
Hello @maraf, could you please provide guidance on where to write Blazor.start({ configureRuntime: runtime => runtime.withConfig({ loadAllSatelliteResources: true }) }) in a Blazor application?
@alexspirou I'm currently using this approach, and did the following:
autostart="false"
to the include statement for the blazor.web.js file:
<script src="_framework/blazor.web.js" autostart="false"></script>
start
method, and link this file in your App.razor:
Blazor.start({
webAssembly: {
configureRuntime: dotnet => {
dotnet.withConfig({ loadAllSatelliteResources: true });
}
}
});
Thanks for the response @joostvz.
var dllBytes = await http.GetByteArrayAsync("/_framework/en-US/WasmBasicTestApp.resources.wasm");
My resources are in a class library under the folder named Resources. How did you get the Assemblies?
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
I'm trying to create a Blazor WebAssembly app where users can switch the display language. This only seems to work after forcing a reload of the page. According to the conversation in dotnet/aspnetcore#50361, switching languages without a page reload is currently not supported in Webassembly. I have a web app where it is not acceptable to reload the page when the user switches the language. A page refresh gives a bad user experience. And our app also contains a form, which data must be preserved when switching to another language.
I found a workaround by using this package: https://github.com/ScarletKuro/Blazor.WebAssembly.DynamicCulture, which calls an internal WebAssembly API:
INTERNAL.loadSatelliteAssemblies
. Normally, Blazor (WebAssembly) calls this method to load the assemblies for the current active culture. The Blazor.WebAssembly.DynamicCulture package calls this method to load the assemblies of all specified cultures. After loading all specified assemblies, it is possible to change the language without a page reload.Describe the solution you'd like
Is it possible to open up the
INTERNAL.loadSatelliteAssemblies
API, so that developers can specify the cultures they want to be loaded? By default it can still load only the current culture, but it would be nice if developers can override this behavior.Edit: My feature request is about opening up this API in a decent way, so that developers don't have to call API's which are marked as internal.
Additional context
No response