多语言(Localization)
本页系统性介绍 Ape‑Volo‑Admin 的多语言实现、资源组织、服务注册、请求文化解析以及在业务中的使用方式。
资源文件位置
静态资源文件位于:Ape.Volo.Common/MultiLanguage/Resources/
- 默认(中性)语言:
Language.resx - 英文:
Language.en.resx - 你可以按需新增:
Language.zh-CN.resx、Language.ja.resx等
核心能力概览
- 使用 .resx 资源与
IStringLocalizer<T>完成字符串本地化(T 为Language)。 - 自定义扩展封装服务注册与请求文化配置:
AddCustomMultiLanguagesService:注册本地化与自定义LocalizationService。UseCustomRequestLocalization:配置请求文化(默认 URL 参数 > Accept-Language > Cookie)。AddDataAnnotationsLocalization:启用模型验证与显示特性的本地化。
- 默认支持语言:
zh-CN、en-US(可通过选项扩展)。
服务注册
在应用启动注册多语言(建议显式设置资源路径与支持语言):
csharp
builder.Services.AddCustomMultiLanguagesService(o =>
{
// 资源路径相对 ResourcesPath 根目录(对应文件夹:Ape.Volo.Common/MultiLanguage/Resources)
o.ResourcesPath = "MultiLanguage/Resources";
o.LocalizationType = typeof(Ape.Volo.Common.MultiLanguage.Resources.Language);
o.DefaultCulture = "zh-CN";
o.SupportedCultures = new[] { "zh-CN", "en-US" };
});
// 启用 DataAnnotations 本地化(用于模型验证/显示)
builder.Services.AddControllers()
.AddDataAnnotationsLocalization(typeof(Ape.Volo.Common.MultiLanguage.Resources.Language));中间件与请求文化
配置请求文化中间件(决定本次请求使用哪种语言):
csharp
app.UseCustomRequestLocalization(o =>
{
o.DefaultCulture = "zh-CN";
o.SupportedCultures = new[] { "zh-CN", "en-US" };
});解析顺序(优先级从高到低):
- URL 参数:
?culture=zh-CN或?ui-culture=en-US - 请求头:
Accept-Language: en-US,en;q=0.9 - Cookie:
.AspNetCore.Culture
设置 Cookie 示例:
csharp
var cookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("en-US"));
Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, cookieValue);资源文件与键约定
- 所有本地化键均存放在
Language*.resx中,建议采用语义化命名:- 页面/域前缀:
User_List_Title、Order_Detail_Total - 校验/错误:
Validation_Required、Error_Unauthorized
- 页面/域前缀:
- 文本带占位符时使用
{0} {1},并在代码中以参数形式传入。
示例(Language.resx):
Hello_User→你好,{0}Validation_Required→必填项
示例(Language.en.resx):
Hello_User→Hello, {0}Validation_Required→Required
在代码中使用
方式一:App 内部类使用(项目封装)
csharp
App.L.R("Tenant.DbType") //返回本地化语言方式二:注入 ILocalizationService(项目封装)
csharp
public class UserAppService
{
private readonly ILocalizationService _ls;
public UserAppService(ILocalizationService ls) => _ls = ls;
public string Welcome(string name)
{
return _ls.R("Hello_User", name); // 根据当前文化返回本地化文本
}
}方式三:注入 IStringLocalizer<Language>(框架原生)
csharp
public class UserController : ControllerBase
{
private readonly IStringLocalizer<Language> _localizer;
public UserController(IStringLocalizer<Language> localizer) => _localizer = localizer;
[HttpGet("welcome")]
public string Welcome(string name) => _localizer["Hello_User", name];
}方式四:DataAnnotations 模型验证/显示
csharp
public class LoginDto
{
[Display(Name = "UserName")] // 键:UserName
[Required(ErrorMessage = "Validation_Required")] // 键:Validation_Required
public string UserName { get; set; }
}已在
AddDataAnnotationsLocalization中配置Language作为资源类型,属性上的键会从Language*.resx读取。
前端如何切换语言
- 方式 A:通过 URL 带上
culture参数,如:/api/user/welcome?culture=en-US - 方式 B:设置请求头
Accept-Language: en-US - 方式 C:设置语言 Cookie(
.AspNetCore.Culture),在 UI 层切换语言后持久化。
前端 fetch 示例:
js
fetch("/api/user/welcome?culture=en-US")
.then((r) => r.text())
.then(console.log);扩展新语言
- 在
Ape.Volo.Common/MultiLanguage/Resources/新增Language.xx.resx,如Language.ja.resx。 - 在启动配置的
SupportedCultures中加入对应文化代码(如ja-JP)。 - 为新文化补充所有缺失的键,未配置的键将回退到默认资源。
资源文件增改需要重新编译后才能生效。
常见问题(FAQ)
- 本地化不生效或总是中文?
- 检查是否调用了
UseCustomRequestLocalization; - 确认 URL/Header/Cookie 的语言值与
SupportedCultures一致(如en-US); ResourcesPath是否与资源实际目录匹配(本项目示例为MultiLanguage/Resources)。
- 检查是否调用了
- 取不到某个键?
- 确认键存在于默认资源
Language.resx; - 多语言文件是否补齐该键;
- 是否区分大小写;编译是否已完成。
- 确认键存在于默认资源
- DataAnnotations 文本仍是英文/未替换?
- 确认已调用
AddDataAnnotationsLocalization(typeof(Language)); - Attribute 上的键需与
Language*.resx对应; - 复杂场景可使用
ErrorMessageResourceType/Name明确指定资源。
- 确认已调用
小结
- 资源集中放在
Ape.Volo.Common/MultiLanguage/Resources/Language*.resx。 - 通过扩展方法统一注册与启用请求文化解析;
- 业务内使用
ILocalizationService或IStringLocalizer<Language>读取文本; - 支持 URL/请求头/Cookie 三种切换方式,便于与前端联动。

