fix locale

This commit is contained in:
2025-12-09 04:09:33 +08:00
parent 429fb39140
commit 24512412e5
7 changed files with 230 additions and 89 deletions

View File

@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Globalization;
using System.Text.Json;
using Microsoft.JSInterop;
@@ -33,7 +34,9 @@ namespace Atomx.Admin.Client.Services
private readonly ILocalizationService _localizationService;
// <20><><EFBFBD>棺culture -> translations
private readonly Dictionary<string, Dictionary<string, string>> _cache = new();
// Use a static concurrent dictionary so files loaded during middleware/server prerender
// are visible to provider instances created later in the same request pipeline.
private static readonly ConcurrentDictionary<string, Dictionary<string, string>> _cache = new();
// <20><><EFBFBD><EFBFBD><EBB5BD><EFBFBD><EFBFBD> culture <20><>ӳ<EFBFBD><D3B3>
private static readonly Dictionary<string, string> ShortToCulture = new(StringComparer.OrdinalIgnoreCase)
@@ -231,6 +234,70 @@ namespace Atomx.Admin.Client.Services
public Task LoadCultureAsync(string culture) => EnsureCultureLoadedAsync(MapToFullCulture(culture));
/// <summary>
/// Server-side synchronous culture set used during prerender to ensure translations
/// are available immediately. This method will attempt to load localization
/// JSON from the server's webroot synchronously and set thread cultures.
/// </summary>
public void SetCultureForServer(string cultureShortOrFull)
{
try
{
var cultureFull = MapToFullCulture(cultureShortOrFull);
if (string.IsNullOrEmpty(cultureFull)) return;
// set thread culture
try
{
var ci = new CultureInfo(cultureFull);
CultureInfo.DefaultThreadCurrentCulture = ci;
CultureInfo.DefaultThreadCurrentUICulture = ci;
_currentCulture = cultureFull;
}
catch { }
// try load from webroot synchronously via IWebHostEnvironment if available
try
{
var envType = Type.GetType("Microsoft.AspNetCore.Hosting.IWebHostEnvironment, Microsoft.AspNetCore.Hosting.Abstractions")
?? Type.GetType("Microsoft.AspNetCore.Hosting.IWebHostEnvironment");
if (envType != null)
{
var env = _sp.GetService(envType);
if (env != null)
{
var webRootProp = envType.GetProperty("WebRootPath");
var contentRootProp = envType.GetProperty("ContentRootPath");
var webRoot = webRootProp?.GetValue(env) as string ?? Path.Combine(contentRootProp?.GetValue(env) as string ?? ".", "wwwroot");
var path = Path.Combine(webRoot ?? ".", "localization", cultureFull + ".json");
if (File.Exists(path))
{
try
{
var json = File.ReadAllText(path);
var dict = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
_cache[cultureFull] = dict;
_logger?.LogInformation("(Server sync) Loaded localization file for {Culture} from path {Path}, entries: {Count}", cultureFull, path, dict.Count);
}
catch (Exception ex)
{
_logger?.LogWarning(ex, "(Server sync) Failed to read localization file synchronously: {Path}", path);
}
}
}
}
}
catch (Exception ex)
{
_logger?.LogDebug(ex, "SetCultureForServer failed to load file for {Culture}", cultureFull);
}
}
catch (Exception ex)
{
_logger?.LogDebug(ex, "SetCultureForServer encountered error");
}
}
private async Task SetCultureInternalAsync(string cultureFull, bool persistCookie)
{
_logger?.LogDebug("SetCultureInternalAsync start: {Culture}, persist={Persist}", cultureFull, persistCookie);