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

.NET 6 ASP MVC控制器返回View前替换HTML标签文本方案咨询

问题

我正在开发一个ASP.NET MVC .NET 6应用程序,默认语言为英语。现要求在管理面板中实现西班牙语、阿拉伯语等多语言选项,为每个页面/视图创建JSON文件存储该页面所有标签的各语言文本,示例格式如下:

[{
  "LabelHtmlId": "FirstName",
  "LablelText" : "User First Name",
  "ScreenId": 1,
  "LanguageCode": "Eng"
},
{
  "LabelHtmlId": "LastName",
  "LablelText" : "User Last Name",
  "ScreenId": 1,
  "LanguageCode": "Eng"
}]

管理员可按上述格式为各页面标签配置不同语言的JSON文件。需求是在控制器的return View()前调用一个函数,传入ScreenId和LanguageCode,从JSON文件中读取内容替换HTML文件中的所有标签文本。例如原标签:

<label id="FirstName">First Name</label>

执行函数后需替换为:

<label id="FirstName">User First Name</label>

我的问题是:如何在Action方法的return View语句前,获取完成模型绑定后的完整HTML,以便解析标签并从JSON文件替换文本?是否可通过自定义ActionExecuted过滤器实现?

注:不接受JavaScript、jQuery等前端方案,因为要求所有操作在服务器端完成,前端方案会先渲染默认文本再替换,影响页面流畅渲染;曾考虑前端替换方案,但会导致用户看到文本切换的变化,不可行;想到使用HTMLAgilityPack,但不知道如何在控制器完成模型绑定后正确实现。

解决方案

一、使用自定义ActionExecuted过滤器实现

完全可以通过自定义ActionExecuted过滤器来实现服务器端的HTML文本替换,具体步骤如下:

  1. 创建标签翻译模型类
    先定义与JSON结构对应的模型,方便序列化/反序列化操作:
public class LabelTranslation
{
    public string LabelHtmlId { get; set; }
    public string LablelText { get; set; } // 与原JSON字段拼写保持一致
    public int ScreenId { get; set; }
    public string LanguageCode { get; set; }
}
  1. 实现自定义ActionExecutedFilter
    在过滤器中,等待视图渲染完成后获取HTML内容,再通过HTMLAgilityPack解析并替换标签文本:
using HtmlAgilityPack;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Text.Json;

public class LanguageTranslationFilter : IAsyncActionExecutedFilter
{
    public async Task OnActionExecutedAsync(ActionExecutedContext context)
    {
        // 仅处理ViewResult类型的返回结果
        if (context.Result is not ViewResult viewResult) return;

        // 1. 获取当前请求的ScreenId和LanguageCode(实际可从路由、Session或用户配置中获取)
        var screenId = 1; // 示例值,需根据业务逻辑调整
        var languageCode = "Eng"; // 示例值,需根据业务逻辑调整

        // 2. 读取对应JSON翻译文件
        var jsonFilePath = Path.Combine(Directory.GetCurrentDirectory(), $"wwwroot/translations/Screen{screenId}_{languageCode}.json");
        if (!File.Exists(jsonFilePath)) return;

        var jsonContent = await File.ReadAllTextAsync(jsonFilePath);
        var translations = JsonSerializer.Deserialize<List<LabelTranslation>>(jsonContent);
        if (translations == null || !translations.Any()) return;

        // 3. 渲染ViewResult为HTML字符串
        var serviceProvider = context.HttpContext.RequestServices;
        var viewExecutor = serviceProvider.GetRequiredService<IViewExecutor>();
        
        var viewContext = new ViewContext(
            context as ActionContext,
            viewResult.View ?? await viewResult.FindView(context),
            viewResult.ViewData,
            viewResult.TempData,
            TextWriter.Null,
            new HtmlHelperOptions()
        );

        using var stringWriter = new StringWriter();
        viewContext.Writer = stringWriter;
        await viewExecutor.ExecuteAsync(viewContext);
        var rawHtml = stringWriter.ToString();

        // 4. 解析HTML并替换标签文本
        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(rawHtml);

        foreach (var translation in translations)
        {
            var targetLabel = htmlDoc.GetElementbyId(translation.LabelHtmlId);
            if (targetLabel != null)
            {
                targetLabel.InnerHtml = translation.LablelText;
            }
        }

        // 5. 将替换后的HTML作为响应返回
        context.Result = new ContentResult
        {
            Content = htmlDoc.DocumentNode.OuterHtml,
            ContentType = "text/html",
            StatusCode = 200
        };
    }
}
  1. 注册过滤器
    可以选择全局注册过滤器,或在指定控制器/Action上添加特性:
// 全局注册(Program.cs中)
builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<LanguageTranslationFilter>();
});

// 或在控制器上单独注册特性
[TypeFilter(typeof(LanguageTranslationFilter))]
public class AdminController : Controller
{
    // 控制器逻辑
}

二、关键注意事项

  • 参数获取方式:ScreenId和LanguageCode可通过路由参数、Session、用户配置信息等方式获取,需结合业务场景调整。
  • JSON文件管理:建议将翻译文件统一存放在wwwroot/translations目录下,采用Screen{ScreenId}_{LanguageCode}.json的命名规范,方便读取和维护。
  • 依赖安装:需通过NuGet安装HTMLAgilityPack包:Install-Package HtmlAgilityPack。
  • 性能优化:可将翻译内容存入内存缓存(如IMemoryCache),避免每次请求都读取JSON文件,提升响应速度。

内容的提问来源于stack exchange,提问作者Noor Uddin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:45:37