C#:如何让CultureInfo按网站当前语言显示翻译后的语言名称
解决多语言网站下拉菜单语言名称本地化显示问题
问题背景
目前已实现获取CultureInfo.NativeName的逻辑,但切换网站配置语言为fr-FR时,页面“All Languages”能正常翻译为“Toutes les langues”,但下拉菜单中的语言名称始终固定显示NativeName,无法随网站当前语言切换而本地化。
期望实现的显示效果:
- 网站语言为en-US时,下拉菜单显示:English、French、German、Spanish
- 网站语言为西班牙语时,下拉菜单显示:Inglés、Francés、Alemán、Español
- 同语言不同地区变体(如es-MX、es-ES)需显示为
Español (MX)、Español (ES)这类符合对应语言习惯的格式
另外发现当前线程区域为ja-JP时,en-US的CultureInfo.DisplayName未按线程区域显示,且要求无需安装额外语言包完成所有功能。当前代码仅通过Dictionary<string, string>存储Culture.Name与Culture.NativeName并绑定下拉菜单。
解决方案
核心思路
放弃仅依赖NativeName的固定逻辑,改为根据网站当前UICulture动态获取语言名称;因无需安装语言包,采用自定义多语言映射表结合地区变体格式化的方式实现稳定的本地化显示。
1. 自定义多语言名称映射表
手动维护各语言在目标UICulture下的翻译,确保无语言包时也能正确显示:
// 定义支持的UICulture与对应语言名称映射 private static readonly Dictionary<string, Dictionary<string, string>> _localizedLanguageNames = new() { { "en-US", new() { {"en-US", "English"}, {"fr-FR", "French"}, {"de-DE", "German"}, {"es-ES", "Spanish"}, {"es-MX", "Spanish (MX)"} } }, { "es-ES", new() { {"en-US", "Inglés"}, {"fr-FR", "Francés"}, {"de-DE", "Alemán"}, {"es-ES", "Español"}, {"es-MX", "Español (MX)"} } }, { "fr-FR", new() { {"en-US", "Anglais"}, {"fr-FR", "Français"}, {"de-DE", "Allemand"}, {"es-ES", "Espagnol"}, {"es-MX", "Espagnol (MX)"} } } }; // 获取指定UICulture下的语言名称,无映射时回退到NativeName private string GetLocalizedLangName(string cultureName, string uiCultureName) { if (_localizedLanguageNames.TryGetValue(uiCultureName, out var uiLangMap) && uiLangMap.TryGetValue(cultureName, out var localizedName)) { return localizedName; } return new CultureInfo(cultureName).NativeName; }
2. 动态绑定下拉菜单
结合当前网站的UICulture,生成符合要求的下拉选项:
// 假设_supportedCultures是网站支持的CultureInfo集合 var currentUiCulture = CultureInfo.CurrentUICulture.Name; var dropdownOptions = _supportedCultures .Select(c => new SelectListItem { Value = c.Name, Text = GetLocalizedLangName(c.Name, currentUiCulture) }) .ToList();
3. 通用地区变体格式化(可选)
如果需要自动处理所有地区变体的格式,无需在映射表中逐个定义,可添加以下逻辑:
private string FormatVariantCultureName(CultureInfo culture, string uiCultureName) { // 获取中立文化(如es-MX的中立文化为es) var neutralCulture = culture.Parent; // 获取中立文化的本地化名称 var neutralLocalizedName = GetLocalizedLangName(neutralCulture.Name, uiCultureName); // 提取地区代码(如MX、ES) var regionCode = culture.Name.Split('-').Last(); return $"{neutralLocalizedName} ({regionCode})"; }
修改GetLocalizedLangName,判断当前culture是否为地区变体后调用此方法:
private string GetLocalizedLangName(string cultureName, string uiCultureName) { var culture = new CultureInfo(cultureName); // 若为地区变体,自动格式化 if (!culture.IsNeutralCulture) { return FormatVariantCultureName(culture, uiCultureName); } if (_localizedLanguageNames.TryGetValue(uiCultureName, out var uiLangMap) && uiLangMap.TryGetValue(cultureName, out var localizedName)) { return localizedName; } return culture.NativeName; }
4. 处理DisplayName不跟随线程区域的问题
默认DisplayName需要对应语言包才能显示正确翻译,若不想依赖语言包,上述自定义映射表是最可靠的方案。如果仍想尝试使用DisplayName,可添加异常捕获回退:
private string GetDisplayNameWithFallback(CultureInfo culture, CultureInfo uiCulture) { try { return culture.DisplayName; } catch (CultureNotFoundException) { // 语言包不存在时回退到自定义映射或NativeName return GetLocalizedLangName(culture.Name, uiCulture.Name); } }
关键注意点
- 自定义映射表需随网站支持的语言和UICulture同步扩展
- 地区变体的显示格式可根据目标UICulture调整(如西班牙语地区可改为
Español (México)) - 自定义映射方案完全不依赖语言包,稳定性更高,适合无权限安装语言包的部署环境
内容的提问来源于stack exchange,提问作者Outside the Box Developer
相关产品推荐
相关产品推荐

