.Net Core Entity MVC多层方案业务逻辑层自定义本地化(Angular前端)实现问询
自定义本地化实现方案(适配.NET Core多层架构)
第一步:自定义语言标识解析中间件
无需依赖系统默认CultureInfo,直接从请求Header中读取自定义语言标识,通过AsyncLocal实现跨层共享上下文,业务逻辑层无需依赖HttpContext即可获取当前语言。
- 自定义语言上下文静态类
public static class CustomLocalizationContext { private static readonly AsyncLocal<string> _currentLanguage = new(); // 可自行修改默认兜底语言 public static string CurrentLanguage { get => _currentLanguage.Value ?? "zh-CN"; set => _currentLanguage.Value = value; } }
- 语言解析中间件
public class CustomLanguageMiddleware { private readonly RequestDelegate _next; public CustomLanguageMiddleware(RequestDelegate next) => _next = next; public async Task InvokeAsync(HttpContext context) { if (context.Request.Headers.TryGetValue("Accept-Language", out var langValue)) { CustomLocalizationContext.CurrentLanguage = langValue.ToString().Trim(); } await _next(context); } }
- 中间件注册(Program.cs中需放在路由注册前)
app.UseMiddleware<CustomLanguageMiddleware>(); // 后续再添加app.UseRouting()等其他中间件
第二步:本地化资源管理服务
基于Entity Framework Code First实现资源持久化,封装通用本地化服务支持全业务复用。
- 本地化资源实体类
public class LocalizationResource { public int Id { get; set; } // 对应自定义语言标识 public string LanguageKey { get; set; } // 资源唯一键,如CSV表头的"UserName"、"CreateTime" public string ResourceKey { get; set; } // 翻译后的内容 public string ResourceValue { get; set; } }
- 在DbContext中注册实体
public DbSet<LocalizationResource> LocalizationResources { get; set; }
执行迁移命令同步表结构到数据库即可。
3. 封装通用本地化服务
public interface ICustomLocalizer { // 单键获取翻译 string GetString(string resourceKey); // 批量获取翻译,适配CSV表头这类多键场景 Dictionary<string, string> GetStrings(IEnumerable<string> resourceKeys); } public class CustomLocalizer : ICustomLocalizer { private readonly YourDbContext _dbContext; public CustomLocalizer(YourDbContext dbContext) => _dbContext = dbContext; public string GetString(string resourceKey) { var currentLang = CustomLocalizationContext.CurrentLanguage; return _dbContext.LocalizationResources .FirstOrDefault(r => r.LanguageKey == currentLang && r.ResourceKey == resourceKey) ?.ResourceValue ?? resourceKey; // 未匹配到翻译直接返回资源键兜底 } public Dictionary<string, string> GetStrings(IEnumerable<string> resourceKeys) { var currentLang = CustomLocalizationContext.CurrentLanguage; var resourceDict = _dbContext.LocalizationResources .Where(r => r.LanguageKey == currentLang && resourceKeys.Contains(r.ResourceKey)) .ToDictionary(r => r.ResourceKey, r => r.ResourceValue); // 补全未匹配到的资源键 foreach (var key in resourceKeys) { resourceDict.TryAdd(key, key); } return resourceDict; } }
- 服务注册(Program.cs)
services.AddScoped<ICustomLocalizer, CustomLocalizer>();
第三步:CSV导出场景使用示例
业务逻辑层直接注入服务即可使用,无需额外传递语言参数:
public class ExportBusinessService { private readonly ICustomLocalizer _localizer; private readonly YourDbContext _dbContext; public ExportBusinessService(ICustomLocalizer localizer, YourDbContext dbContext) { _localizer = localizer; _dbContext = dbContext; } public async Task<byte[]> ExportUserListCsvAsync() { // 1. 定义CSV表头的资源键集合 var headerKeys = new List<string> { "UserName", "Email", "CreateTime", "AccountStatus" }; // 2. 批量获取翻译后的表头 var translatedHeaders = _localizer.GetStrings(headerKeys); // 3. 查询业务数据 var userList = await _dbContext.Users.ToListAsync(); // 4. 原有CSV生成逻辑直接替换表头为translatedHeaders即可 // 省略CSV拼接、编码等原有逻辑 } }
优化建议
- 给
LocalizationResource表加LanguageKey和ResourceKey的联合唯一索引,大幅提升翻译查询性能 - 新增内存/分布式缓存层,缓存已查询过的翻译资源,降低数据库压力;资源更新时同步清理对应缓存即可
- 可配套开发翻译资源后台管理页面,支持可视化增删改翻译内容,无需修改代码即可迭代翻译配置
- 除CSV导出外,接口响应消息、业务字段展示等所有需要多语言的场景均可直接注入
ICustomLocalizer复用能力
内容的提问来源于stack exchange,提问作者qqtf
相关产品推荐
相关产品推荐

