包含动态变量时的ASP .NET MVC本地化?

时间:2012-02-26 15:57:32

标签: asp.net-mvc asp.net-mvc-3 razor localization resources

如果需要本地化,请考虑以下字符串:

You need to write <b>@ViewBag.CharacterAmount</b> characters to be able to 
hand-in this homework. You're still missing <b id="charactersRemaining">
@ViewBag.CharacterAmount</b> characters to reach this limit.

最好的方法是什么?使用string.Format有点复杂,因为ASP .NET MVC逃脱了HTML代码,而且,我宁愿在我的资源文件中没有HTML代码。但是,我仍然需要能够在JavaScript中的b标记中引用这些值。

有什么想法吗?当你进行本地化时,你对此有何看法?

1 个答案:

答案 0 :(得分:1)

您可以编写自定义帮助程序:

public static class ResourcesExtensions
{
    public static IHtmlString Resource(this HtmlHelper htmlHelper, string message, params object[] args)
    {
        var parameters = args.Select(x => htmlHelper.Encode(x)).ToArray();
        return new HtmlString(string.Format(message, parameters));
    }
}

正如您所见,HTML帮助程序仅对值进行编码。我们可以完全控制消息的其余部分,因为它位于资源文件中,我们认为它是有效的HTML,因此XSS没有问题。

然后为您的项目提供一个资源文件,其中包含以下密钥:

MyMessage = You need to write <b>{0}</b> characters to be able to hand-in this homework. You're still missing <b id="charactersRemaining">{1}</b> characters to reach this limit.

然后不要忘记使用PublicResXFileCodeGenerator自定义工具标记此资源文件,以便Visual Studio生成一个允许您访问视图中属性的公共类。

最后在视图中:

@Html.Resource(Resources.MyMessage, (int)ViewBag.CharacterAmount, (int)ViewBag.CharacterAmount)

您需要强制转换的原因是因为扩展方法无法分派动态参数。但显然这根本不是问题,因为您不应该使用ViewBag / ViewData,但是您应该使用视图模型和强类型视图模型,因此在您的真实代码中您将拥有:

@Html.Resource(Resources.MyMessage, Model.CharacterAmount, Model.CharacterAmount)

这种方法的一个缺点是我们在资源文件中移动了一些标记,遗憾的是这可能会使视图变得不那么容易理解,当我们需要修改它时,我们应该在所有本地化版本中执行此操作。

另一种方法当然是将此标记的每个不同部分放入资源文件,然后:

@Resources.YouNeedToWrite <b>ViewBag.CharacterAmount</b> @Resources.StillMissing 
<b id="charactersRemaining">ViewBag.CharacterAmount</b> @(Resources.ToReachLimit).