You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于用户语言在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:35:35