基于用户语言在ASP.NET Core Razor Pages渲染本地化嵌套JSON
嘿,我来帮你搞定这个嵌套JSON本地化的需求!结合你已经有的ASP.NET Core Razor Pages(net5.0)resx本地化基础,我们可以分几步实现这个功能,直接上干货:
实现步骤
1. 先搞定JSON文件和数据模型
首先咱们得把结构化的JSON本地化文件和对应的数据模型准备好,这样才能把JSON数据映射到C#对象里方便渲染。
1.1 创建本地化JSON文件
在项目根目录新建Resources文件夹,然后添加对应语言的JSON文件:
- 英文版本(Tools.en.json):
{ "Categories": [ { "Name": "Development Tools", "Tools": [ { "Name": "Visual Studio" }, { "Name": "JetBrains Rider" } ] }, { "Name": "Testing Tools", "Tools": [ { "Name": "Selenium" }, { "Name": "NUnit" } ] } ] }
- 俄文版本(Tools.ru.json):
{ "Categories": [ { "Name": "Инструменты разработки", "Tools": [ { "Name": "Visual Studio" }, { "Name": "JetBrains Rider" } ] }, { "Name": "Инструменты тестирования", "Tools": [ { "Name": "Selenium" }, { "Name": "NUnit" } ] } ] }
1.2 定义对应的数据模型
在项目里建个Models文件夹,添加以下类来匹配JSON的结构:
public class Tool { public string Name { get; set; } } public class ToolCategory { public string Name { get; set; } public List<Tool> Tools { get; set; } = new List<Tool>(); } public class ToolLocalizationData { public List<ToolCategory> Categories { get; set; } = new List<ToolCategory>(); }
2. 配置Startup.cs(net5.0专属)
你已经有resx本地化的配置了,现在只需添加JSON本地化的支持,同时确保文化切换逻辑正常工作:
2.1 完善ConfigureServices方法
把这些代码加进去(注意和你现有的配置合并):
using Microsoft.AspNetCore.Localization; using System.Globalization; using System.IO; public void ConfigureServices(IServiceCollection services) { // 保留你已有的Razor Pages配置 services.AddRazorPages(); // 配置支持的语言(英文、俄文) var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("ru") }; // 配置本地化选项,和你resx的配置保持一致 services.Configure<RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; // 启用Cookie和QueryString两种文化切换方式(和你现有resx配置对齐) options.RequestCultureProviders = new List<IRequestCultureProvider> { new CookieRequestCultureProvider(), new QueryStringRequestCultureProvider() }; }); // 注册用于读取JSON本地化数据的服务 services.AddHttpContextAccessor(); // 必须加,用来获取当前请求的文化 services.AddScoped<IToolLocalizationService, ToolLocalizationService>(); }
2.2 完善Configure方法
别忘了添加请求本地化中间件(要放在UseRouting之前):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 保留你已有的中间件(比如异常处理、静态文件等) // 启用请求本地化 app.UseRequestLocalization(app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value); app.UseRouting(); // 保留其他中间件(授权、端点路由等) app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
2.3 实现本地化服务
新建一个服务类,用来根据当前请求的文化加载对应的JSON文件:
public interface IToolLocalizationService { Task<ToolLocalizationData> GetLocalizedToolDataAsync(); } public class ToolLocalizationService : IToolLocalizationService { private readonly IHttpContextAccessor _httpContextAccessor; private readonly IWebHostEnvironment _env; public ToolLocalizationService(IHttpContextAccessor httpContextAccessor, IWebHostEnvironment env) { _httpContextAccessor = httpContextAccessor; _env = env; } public async Task<ToolLocalizationData> GetLocalizedToolDataAsync() { // 获取当前请求的语言文化 var currentCulture = _httpContextAccessor.HttpContext.Features.Get<IRequestCultureFeature>().RequestCulture.Culture.Name; // 拼接JSON文件路径 var jsonPath = Path.Combine(_env.ContentRootPath, "Resources", $"Tools.{currentCulture}.json"); // 如果当前语言的文件不存在,回退到英文 if (!File.Exists(jsonPath)) { jsonPath = Path.Combine(_env.ContentRootPath, "Resources", "Tools.en.json"); } // 读取JSON并绑定到模型 var jsonContent = await File.ReadAllTextAsync(jsonPath); return System.Text.Json.JsonSerializer.Deserialize<ToolLocalizationData>(jsonContent); } }
3. 在Razor Page里渲染数据
现在就可以在页面里获取并展示本地化的嵌套数据了:
3.1 修改PageModel(比如Index.cshtml.cs)
注入咱们的服务,在OnGet方法里获取数据:
public class IndexModel : PageModel { private readonly IToolLocalizationService _toolLocalizationService; public ToolLocalizationData ToolData { get; set; } public IndexModel(IToolLocalizationService toolLocalizationService) { _toolLocalizationService = toolLocalizationService; } public async Task OnGetAsync() { ToolData = await _toolLocalizationService.GetLocalizedToolDataAsync(); } }
3.2 修改Razor视图(Index.cshtml)
用循环渲染分类和工具,还可以加个语言切换按钮:
@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="container mt-4"> <h1>@Localizer["Tools"]</h1> <!-- 这里继续用你已有的resx本地化文本 --> @foreach (var category in Model.ToolData.Categories) { <div class="card mb-3"> <div class="card-header"> <h2>@category.Name</h2> </div> <div class="card-body"> <ul class="list-group"> @foreach (var tool in category.Tools) { <li class="list-group-item">@tool.Name</li> } </ul> </div> </div> } </div> <!-- 语言切换按钮,点击后会通过QueryString切换文化 --> <div class="container mt-3"> <a asp-page="./Index" asp-route-culture="en">English</a> | <a asp-page="./Index" asp-route-culture="ru">Русский</a> </div>
4. 测试和注意事项
- 文化切换测试:点击语言切换链接,或者手动在URL后加
?culture=ru,就能看到俄文的分类名称了。 - 回退机制:如果某个语言的JSON文件没找到,会自动用英文版本兜底。
- JSON文件属性:右键JSON文件,把“复制到输出目录”设为“如果较新则复制”,不然发布后可能找不到文件。
- 和resx共存:这个方案和你现有的resx本地化完全兼容,resx用来处理零散文本(比如页面标题),JSON用来处理结构化的嵌套数据,完美搭配。
内容的提问来源于stack exchange,提问作者The Neighbors Kid
相关产品推荐
相关产品推荐

