ASP .NET MVC локализация, когда включены динамические переменные? - PullRequest
1 голос
/ 26 февраля 2012

Рассмотрим следующую строку, если мне нужно ее локализовать:

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-код в моих файлах ресурсов.Однако мне все еще нужно иметь возможность ссылаться на эти значения внутри тегов b из JavaScript.

Есть идеи?Какой у вас подход к этому, когда вы делаете локализацию?

1 Ответ

1 голос
/ 26 февраля 2012

Вы можете написать собственный помощник:

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).
...