当前位置: 首页 > news >正文

ABP vNext 多语言与本地化:动态切换、资源继承与热更新

🚀 ABP vNext 多语言与本地化:动态切换、资源继承与热更新 🎉


📩 用户请求
🛠️ UseRequestLocalization
🔍 QueryString / Cookie / Accept-Language
🌍 确定 CultureInfo
📦 加载 JSON 资源 (嵌入/物理)
🔤 注入 IStringLocalizer 渲染文本
🔄 资源回退链: Shared → Validation → UI → Custom
🖥️ Blazor / Razor / JS 前端渲染

📑 目录

  • 🚀 ABP vNext 多语言与本地化:动态切换、资源继承与热更新 🎉
    • 📌 前置 `using` 声明
    • 🚀 模块化资源 & 默认文化
      • 📁 目录结构 & 嵌套分组示例
      • 📝 注册资源:DefaultResourceCulture vs SupportedCultures
    • 🔧 请求本地化管道 & 中间件顺序
    • 🌐 前端多端渲染示例
      • 1. Razor / MVC
      • 2. Blazor Server / WASM 完整 CultureSwitcher
    • 🔄 运行时切换 & 安全 Cookie
    • 🔥 开发环境 JSON 热更新
    • 🔗 资源继承与回退顺序
    • 🧪 集成测试覆盖示例
    • 📈 监控 & 日志埋点
    • 📅 日期/数字格式化示例
    • 💻 Angular/React 前端示例
    • ✅ 总结一览


📌 前置 using 声明

using System.Globalization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Volo.Abp.Localization;
using Volo.Abp.VirtualFileSystem;

🚀 模块化资源 & 默认文化

📁 目录结构 & 嵌套分组示例

Localization/
└── YourModule/├── en.json└── zh-Hans.json

示例(zh-Hans.json)

{"User": {"Greeting": "你好,{0}","Profile": "个人信息"},"Validation": {"FieldIsRequired": "这是必填字段"}
}

📝 注册资源:DefaultResourceCulture vs SupportedCultures

Configure<AbpLocalizationOptions>(options =>
{options.Resources// "zh-Hans" 是 DefaultResourceCulture(资源回退基准),非 SupportedCultures.Add<YourResource>("zh-Hans")// 回退链注释:SharedResource → AbpValidationResource → AbpUiResource → YourResource.AddBaseTypes(typeof(SharedResource),typeof(AbpValidationResource),typeof(AbpUiResource)).AddVirtualJson("/Localization/YourModule");// 列出语言供管道使用(SupportedCultures 在 RequestLocalizationOptions 中配置)options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文", isDefault: true));options.Languages.Add(new LanguageInfo("en",      "en",      "English"));
});

🔧 请求本地化管道 & 中间件顺序

builder.Services.AddLocalization();var cultures = new[] { new CultureInfo("zh-Hans"), new CultureInfo("en") };builder.Services.Configure<RequestLocalizationOptions>(options =>
{options.DefaultRequestCulture     = new RequestCulture("zh-Hans");options.SupportedCultures         = cultures;options.SupportedUICultures       = cultures;options.FallBackToParentCultures   = true;  // 自动回退至父文化options.FallBackToParentUICultures = true;// 先查 QueryString → 再 Cookie → 默认 Accept-Language Headeroptions.RequestCultureProviders.Insert(0, new QueryStringRequestCultureProvider());options.RequestCultureProviders.Insert(1, new CookieRequestCultureProvider());
});

管道中顺序

app.UseRequestLocalization();    // 必须在 Routing/Auth 之前
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// app.UseAbpRequestLocalization(); // 如使用 ABP 扩展,可替换或调整位置

🌐 前端多端渲染示例

1. Razor / MVC

@inject IStringLocalizer<YourResource> L<h1>@L["User:Greeting", "张三"]</h1>
[LocalizationResourceName("YourResource")]
public class HomeController : AbpController {}

2. Blazor Server / WASM 完整 CultureSwitcher

@inject IStringLocalizer<YourResource> L
@inject IJSRuntime JSRuntime<select @onchange="OnCultureChanged"><option value="zh-Hans">🇨🇳 简体中文</option><option value="en">🇬🇧 English</option>
</select><h3>@L["Welcome"]</h3>@code {private async Task OnCultureChanged(ChangeEventArgs e){var culture = e.Value?.ToString()!;var cookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture));// 写入 Cookieawait JSRuntime.InvokeVoidAsync("blazorCulture.set", cookieValue);// 更新 .NET 线程文化var ci = new CultureInfo(culture);CultureInfo.DefaultThreadCurrentCulture    = ci;CultureInfo.DefaultThreadCurrentUICulture = ci;StateHasChanged(); // 强制刷新 UI}
}

注意:在 _Host.cshtmlindex.html 中添加:

<script>window.blazorCulture = {set: function (cookieValue) {document.cookie = ".AspNetCore.Culture=" + cookieValue + ";path=/;";}};
</script>

🔄 运行时切换 & 安全 Cookie

public IActionResult SetLanguage(string culture)
{var cookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture));Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName,cookieValue,new CookieOptions {Path       = "/",Expires    = DateTimeOffset.UtcNow.AddYears(1),HttpOnly   = true,Secure     = true,SameSite   = SameSiteMode.Lax});return Redirect(Request.Headers["Referer"].ToString());
}

🔥 开发环境 JSON 热更新

Configure<AbpVirtualFileSystemOptions>(options =>
{if (env.IsDevelopment()){// 泛型为模块的 ApplicationModule 类型options.FileSets.ReplaceEmbeddedByPhysical<YourModuleApplicationModule>(Path.Combine(env.ContentRootPath, "Localization/YourModule"));}
});

生产环境:移除此替换,使用嵌入资源提高 I/O 性能。


🔗 资源继承与回退顺序

  1. SharedResource(业务/共用文案)
  2. AbpValidationResource(验证提示)
  3. AbpUiResource(通用 UI 文案)
  4. YourResource(模块专属文案)
options.Resources.Add<YourResource>("zh-Hans").AddBaseTypes(typeof(SharedResource),typeof(AbpValidationResource),typeof(AbpUiResource));

🧪 集成测试覆盖示例

[Fact]
public async Task Localizer_Should_Return_Correct_Text_By_Cookie()
{var host = await new WebHostBuilder().UseStartup<Startup>().StartAsync();var client = host.GetTestClient();client.DefaultRequestHeaders.Add("Cookie", ".AspNetCore.Culture=c=zh-Hans|uic=zh-Hans");var response = await client.GetAsync("/Home/Index");var html = await response.Content.ReadAsStringAsync();Assert.Contains("欢迎使用 ABP", html);
}

补充:可再增加 QueryString 和 Accept-Language 的测试场景 🧪


📈 监控 & 日志埋点

builder.Services.Configure<RequestLocalizationOptions>(opts =>
{opts.Events = new RequestLocalizationEvents{OnRequestCultureResolved = ctx =>{logger.LogInformation("🌐 Culture resolved: {Culture} via {Provider}",ctx.RequestCulture.Culture,ctx.Provider.GetType().Name);return Task.CompletedTask;}};
});

📅 日期/数字格式化示例

@inject IStringLocalizer<YourResource> L<p>📆 @DateTime.Now.ToString("D", CultureInfo.CurrentCulture)</p>
<p>💰 @(1234567.89.ToString("N", CultureInfo.CurrentCulture))</p>

💻 Angular/React 前端示例

import { localization } from '@abp/ng.core'; // Angular
const l = await localization.getResource('YourResource');
console.log(l.User.Greeting('王五')); // 你好,王五import { localization as localeR } from '@abp/react'; // React
const l2 = await localeR.getResource('YourResource');
console.log(l2.User.Profile); // 个人信息

或手动:

async function setCulture(culture) {document.cookie = ".AspNetCore.Culture=c=" + culture + "|uic=" + culture + ";path=/;";window.location.reload();
}

✅ 总结一览

能力实现状态备注
模块化资源DefaultResourceCulture + AddVirtualJson
请求本地化管道QueryString/Cookie/Accept-Language + UseRequestLocalization
UI 渲染Razor/MVC + Blazor/CultureSwitcher + JS 前端支持
运行时切换安全 Cookie 配置
JSON 热更新✅(开发)ReplaceEmbeddedByPhysical
资源继承 & 回退Shared → Validation → UI → YourResource
集成测试覆盖TestServer + Cookie/QueryString/Accept-Language 测试
日志 & 监控RequestLocalizationEvents.OnRequestCultureResolved
自动回退父文化FallBackToParentCultures/UICultures
多前端框架支持Angular/React + ABP JS API 示例

相关文章:

  • 微信小程序使用图片实现红包雨功能
  • error:MISCONF Redis is configured to save RDB snapshots
  • 计算机网络-自顶向下—第五章数据链路层重点复习笔记
  • 《高并发系统性能优化三板斧:缓存 + 异步 + 限流》
  • Nginx+keepalived主从,双主架构
  • git-build-package 工具代码详细解读
  • Git常用命令摘要
  • 青少年编程与数学 01-011 系统软件简介 19 SSMS 数据库管理工具
  • 【AS32系列MCU调试教程】性能优化:Eclipse环境下AS32芯片调试效率提升
  • Java 与 MySQL 性能优化:Linux服务器上MySQL性能指标解读与监控方法
  • Spring MVC 中日期格式转换的两种实用方法
  • ​​实时人脸检测与人脸关键点识别系统实现
  • 简历模板3——数据挖掘工程师5年经验
  • 【机器学习与数据挖掘实战 | 医疗】案例16:基于K-Means聚类的医疗保险的欺诈发现
  • 提的缺陷开发不改,测试该怎么办?
  • shell编程语言-1 shell脚本基础
  • Docker 基础使用
  • 分类预测 | Matlab基于AOA-VMD-LSTM故障诊断分类预测
  • MVVM模式中,BaseViewModel 的 IsBusy 属性的作用
  • 矩阵混剪系统源码搭建全流程技术解析,矩阵OEM
  • 广州网站建设公司网络安全优化/站长之家查询域名
  • 网站开发和软件测试哪个好/广告联盟app推广
  • 万维建设网站/成人短期培训学校
  • 版权下如何做免费电影网站/宁波seo博客
  • 网站的管理页面/下载百度浏览器
  • 网站搜索栏建立/seo价格是多少