CodeSpirit 多语言国际化使用指南(Beta)
概述
CodeSpirit 框架现已支持完整的前后端多语言国际化功能,提供中英文双语支持,基于 .NET 资源文件和 AMIS locale,通过 Settings 组件实现全局、租户、用户三级语言配置。
版本: v1.0.0
支持语言: 简体中文(zh-CN)、英文(en)
更新日期: 2025年12月28日
- Github:xin-lai/CodeSpirit
- Gitee:magicodes/CodeSpirit
🎯 核心特性
- ✅双语支持:中文(默认)+ 英文
- ✅全栈覆盖:后端 API + 前端 UI
- ✅多级配置:系统默认 → 租户默认 → 用户偏好
- ✅类型安全:使用 .resx 资源文件,编译时强类型访问
- ✅动态切换:用户可实时切换语言,无需重新登录
- ✅AMIS 兼容:集成 AMIS 的 locale 机制
- ✅DataAnnotations 支持:验证特性自动本地化
- ✅DTO描述多语言:支持字段描述信息的多语言
- ✅零侵入:无需修改业务表结构,基于 Settings 组件
🏗️ 架构设计
语言解析优先级
Cookie(用户手动切换) ↓ (未设置) User Settings(用户偏好) ↓ (未设置) Tenant Settings(租户默认) ↓ (未设置) Global Settings(系统默认) ↓ (未设置) zh-CN(最终回退)Settings 存储结构
// 全局默认语言 Module: "Localization" Key: "DefaultLanguage" Value: "zh-CN" Scope: Global // 租户默认语言 Module: "Localization" Key: "DefaultLanguage" Value: "en" Scope: Tenant ScopeId: "{tenantId}" // 用户偏好语言 Module: "Localization" Key: "PreferredLanguage" Value: "en" Scope: User ScopeId: "{userId}"🚀 快速开始
1. 配置已完成
本地化服务已在ServiceDefaults中自动注册,无需额外配置。
2. 后端使用
在 Controller 中使用本地化
using CodeSpirit.Localization.Resources; using Microsoft.Extensions.Localization; public class MyController : ApiControllerBase { private readonly IStringLocalizer<SharedResources> _localizer; public MyController(IStringLocalizer<SharedResources> localizer) { _localizer = localizer; } [HttpPost] public IActionResult Create() { return Ok(new ApiResponse { Status = 1, Msg = _localizer["Common.Save"].Value }); } }抛出本地化异常
// 使用资源键 throw new BusinessException("Errors.InvalidStartTime"); // 带参数 throw new ValidationException("Errors.NotFound", resourceId);3. DTO 验证特性多语言
using CodeSpirit.Localization.Resources; public class CreateQuestionDto { [Display(Name = "Content", ResourceType = typeof(DisplayResources))] [Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "Required")] [StringLength(2000, ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "StringLengthMax")] public string Content { get; set; } = string.Empty; }验证错误示例:
中文环境:题目内容不能为空
英文环境:Content is required
4. DTO 描述信息多语言
DTO 字段的描述信息(Description)也支持多语言,通过LocalizedDescriptionAttribute实现。
4.1 创建服务资源文件
各服务应创建自己的资源文件,保持服务独立性:
资源文件结构:
CodeSpirit.ExamApi/Resources/ ├── ExamDisplayResources.cs # 资源占位类(包含ResourceManager) ├── ExamDisplay.resx # 中文资源 └── ExamDisplay.en.resx # 英文资源资源键命名规范:
- DTO字段描述:
Description.{EntityName}.{PropertyName} - 示例:
Description.Question.Options、Description.Question.CorrectAnswer
4.2 在DTO中使用
using CodeSpirit.Core.Attributes; using CodeSpirit.ExamApi.Resources; public class CreateQuestionDto { [LocalizedDescription( "根据题目内容生成合适的选项", // 回退文本(可选) ResourceKey = "Description.Question.Options", ResourceType = typeof(ExamDisplayResources) )] public List<string> Options { get; set; } }使用方式:
- 方式1:仅使用资源键(推荐)
- 方式2:带回退文本(更安全,资源不可用时显示回退文本)
- 方式3:使用共享资源(仅适用于通用描述)
4.3 向后兼容
现有的DescriptionAttribute仍然可以正常使用,系统会优先检查LocalizedDescriptionAttribute,如果不存在则回退到DescriptionAttribute。
4.4 资源文件组织原则
- 共享资源:
CodeSpirit.Localization/Resources/- 存放真正通用的、跨服务的资源 - 服务资源:
ApiServices/{ServiceName}/Resources/- 存放服务特有的业务资源
最佳实践:
- 各服务管理自己的资源文件,避免在共享资源中放置服务特定内容
- 遵循
Description.{EntityName}.{PropertyName}命名约定 - 建议提供回退文本,确保资源不可用时仍能显示
4.5 技术实现
描述多语言的资源解析由 AMIS 表单生成时统一处理:
- CultureResolver:从 HttpContext Features、Cookie 等多个来源获取当前语言
- 统一解析:
GetLocalizedDescription方法在表单生成时解析资源 - 回退机制:英文环境下确保正确加载英文资源,避免回退到中文
- 缓存优化:在同一请求中复用已解析的文化信息
5. 前端使用
JavaScript
// 获取翻译文本 const message = CodeSpirit.i18n.t('Common.Save'); // 带参数 const message = CodeSpirit.i18n.t('Validation.Required', { 0: '用户名' }); // 切换语言 CodeSpirit.i18n.switchLanguage('en');Razor 页面
@using CodeSpirit.Localization.Resources @using Microsoft.Extensions.Localization @inject IStringLocalizer<SharedResources> Localizer <h1>@Localizer["Common.Save"]</h1>🎛️ 语言配置管理
通过 API 设置语言
系统已自动集成 Settings 组件,可以通过 Settings API 管理语言配置:
设置用户语言偏好
await _settingsService.SetUserSettingAsync( module: "Localization", key: "PreferredLanguage", value: "en", userId: currentUserId );设置租户默认语言
await _settingsService.SetTenantSettingAsync( module: "Localization", key: "DefaultLanguage", value: "en", tenantId: currentTenantId );设置全局默认语言
await _settingsService.SetGlobalSettingAsync( module: "Localization", key: "DefaultLanguage", value: "en" );通过 UI 切换语言
用户可以在导航栏的语言切换器中选择语言,切换后会:
- 设置 Cookie(
.AspNetCore.Culture) - 刷新页面
- 所有界面文本、错误消息自动切换为对应语言
📚 资源文件说明
共享资源(Localization组件)
| 资源文件 | 用途 | 示例键 |
|---|---|---|
Shared.resx | 通用 UI 文本 | Common.Save,Common.Cancel |
Errors.resx | 错误消息 | Errors.NotFound,Errors.Unauthorized |
Validation.resx | 验证消息模板 | Required,StringLengthMax |
Display.resx | 字段显示名称 | Content,Type,Difficulty |
每个资源文件都有对应的英文版本(如Shared.en.resx)。
服务特定资源(各API服务)
各服务应创建自己的资源文件,保持服务独立性:
命名规范:
- 占位类:
{ServiceName}DisplayResources.cs - 资源文件:
{ServiceName}Display.resx、{ServiceName}Display.en.resx
示例:
CodeSpirit.ExamApi/Resources/ ├── ExamDisplayResources.cs # 资源占位类(包含ResourceManager) ├── ExamDisplay.resx # 中文资源 └── ExamDisplay.en.resx # 英文资源 CodeSpirit.SurveyApi/Resources/ ├── SurveyDisplayResources.cs ├── SurveyDisplay.resx └── SurveyDisplay.en.resx资源键命名约定:
- DTO字段描述:
Description.{EntityName}.{PropertyName} - 示例:
Description.Question.Options、Description.Survey.Title
🔧 常见场景
场景 1:用户切换语言
用户在导航栏选择 "English"
JavaScript 调用
CodeSpirit.i18n.switchLanguage('en')设置 Cookie 并刷新页面
所有内容显示为英文
场景 2:租户设置默认语言
- 租户管理员在设置中选择默认语言为英文
- 系统通过 Settings API 保存配置
- 该租户下的所有用户默认使用英文
- 用户仍可以设置自己的语言偏好
场景 3:API 返回本地化错误
// 中文环境 throw new BusinessException("Errors.NotFound"); // API 返回: { "status": 0, "msg": "未找到资源" } // 英文环境 throw new BusinessException("Errors.NotFound"); // API 返回: { "status": 0, "msg": "Resource not found" }