Skip to content

多语言(Localization)

本页系统性介绍 Ape‑Volo‑Admin 的多语言实现、资源组织、服务注册、请求文化解析以及在业务中的使用方式。

资源文件位置

静态资源文件位于:Ape.Volo.Common/MultiLanguage/Resources/

  • 默认(中性)语言:Language.resx
  • 英文:Language.en.resx
  • 你可以按需新增:Language.zh-CN.resxLanguage.ja.resx

核心能力概览

  • 使用 .resx 资源与 IStringLocalizer<T> 完成字符串本地化(T 为 Language)。
  • 自定义扩展封装服务注册与请求文化配置:
    • AddCustomMultiLanguagesService:注册本地化与自定义 LocalizationService
    • UseCustomRequestLocalization:配置请求文化(默认 URL 参数 > Accept-Language > Cookie)。
    • AddDataAnnotationsLocalization:启用模型验证与显示特性的本地化。
  • 默认支持语言:zh-CNen-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" };
});

解析顺序(优先级从高到低):

  1. URL 参数:?culture=zh-CN?ui-culture=en-US
  2. 请求头:Accept-Language: en-US,en;q=0.9
  3. Cookie:.AspNetCore.Culture

设置 Cookie 示例:

csharp
var cookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture("en-US"));
Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, cookieValue);

资源文件与键约定

  • 所有本地化键均存放在 Language*.resx 中,建议采用语义化命名:
    • 页面/域前缀:User_List_TitleOrder_Detail_Total
    • 校验/错误:Validation_RequiredError_Unauthorized
  • 文本带占位符时使用 {0} {1},并在代码中以参数形式传入。

示例(Language.resx):

  • Hello_User你好,{0}
  • Validation_Required必填项

示例(Language.en.resx):

  • Hello_UserHello, {0}
  • Validation_RequiredRequired

在代码中使用

方式一: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);

扩展新语言

  1. Ape.Volo.Common/MultiLanguage/Resources/ 新增 Language.xx.resx,如 Language.ja.resx
  2. 在启动配置的 SupportedCultures 中加入对应文化代码(如 ja-JP)。
  3. 为新文化补充所有缺失的键,未配置的键将回退到默认资源。

资源文件增改需要重新编译后才能生效。


常见问题(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
  • 通过扩展方法统一注册与启用请求文化解析;
  • 业务内使用 ILocalizationServiceIStringLocalizer<Language> 读取文本;
  • 支持 URL/请求头/Cookie 三种切换方式,便于与前端联动。

版权所有 © 2021-2026 ApeVolo-Team