#asp.net-mvc-3 #internationalization #razor
#asp.net-mvc-3 #интернационализация #razor
Вопрос:
Раньше у меня было что-то вроде этого:
We suggest you read our @Html.ActionLink("help page", "Help", "Home") before
proceeding.
красиво и чисто. затем я решил, что нам нужно интернационализировать приложение. Я не смог придумать лучшего способа справиться с вышесказанным, чем сохранить следующую строку в файле ресурсов:
We suggest you read our [HelpPage] before proceeding.
и затем в представлении, которое я должен выполнить:
@MvcHtmlString.Create(this.Resource("Help").ToString()
.Replace("[HelpPage]",
@Html.ActionLink("help page", "Help", "Home").ToString()
)
)
Какие еще стратегии вы можете использовать для интернационализации с помощью Razor?
this.Resource()
это расширение страницы, которое вызывает .GetLocalResourceObject()
и возвращает MvcHtmlString
Ответ №1:
Вы должны создать отдельный кодовый метод, который заменяет любые [placeholder]
s фактическими ссылками, затем вызвать этот помощник в представлениях Razor.
Это даст вам единственное место для изменения кода, который заполняет ссылки.
Комментарии:
1. звучит разумно, но я не могу до конца это продумать… так что бы я сделал
@Html.MyFn("Help", @Html.ActionLink())
? это действительно похоже на создание шаблонов… вышесказанное было бы хорошо для замены одного «тега», но если бы у меня было 2, это усложнялось … мысли?2. @ekkis: Вы должны выполнить замену тега в функции.
3. да, но проблема в том, что нет хорошего способа сделать это универсальным … если только я не должен был передать словарь, где термин является токеном для замены, а определение некоторым фрагментом кода для запуска, например,
Dictionary<string, code> tags = new Dictionary<string, string>() { "Help", "@Html.ActionLink(...)" }; @Html.MyFn(tags)
где myFn прочитал бы вторую строку и eval() ее (каким-то образом — я еще не настолько хорошо разбираюсь в C #, чтобы знать как)4. @ekkis: Именно. ЭТО должно быть a
Dictionary<string, Func<string, IHtmlString>>
; значениями должны быть делегаты, которые вы можете вызывать с помощью[contents]
. Это дает вам единое место для размещения всех тегов.
Ответ №2:
У меня была такая же проблема. Вместо использования заполнителей я использую то же форматирование в своих строках ресурсов, как если бы я использовал String.Format()
. Пример использования этого; мои строки ресурсов
LogOnText1 | Please enter your user name and password. {0} if you don't have an account.
LogOnText1Register | Register
и мой взгляд (razor):
@MvcHtmlString.Create(String.Format(ViewRes.AccountStrings.LogOnText1,
Html.ActionLink(ViewRes.AccountStrings.LogOnText1Register, "Register")))
Я думаю, что это немного чище
Комментарии:
1. это достойный подход, но мне никогда не нравилась его позиционность. Обсуждение SLaks на самом деле закончилось тем, что привело к хорошему решению. Я отвечу на это здесь, чтобы закрыть проблему
Ответ №3:
итак, вот что я в итоге написал:
public static class PageExtensions
{
public static MvcHtmlString Resource(
this WebViewPage page, string key,
Dictionary<string, MvcHtmlString> tokenMap
) {
HttpContextBase http = page.ViewContext.HttpContext;
string text = (string) http.GetLocalResourceObject(page.VirtualPath, key);
return new TagReplacer(text, tokenMap).ToMvcHtmlString();
}
где замены тегов выполняются следующим образом:
public class TagReplacer
{
Dictionary<string, MvcHtmlString> tokenmap;
public string Value { get; set; }
public TagReplacer(string text, Dictionary<string, MvcHtmlString> tokenMap)
{
tokenmap = tokenMap;
Regex re = new Regex(@"[.*?]", RegexOptions.IgnoreCase);
Value = re.Replace(text, new MatchEvaluator(this.Replacer));
}
public string Replacer(Match m)
{
return tokenmap[m.Value.RemoveSet("[]")].ToString();
}
public MvcHtmlString ToMvcHtmlString()
{
return MvcHtmlString.Create(Value);
}
}
итак, в моем коде я теперь могу называть это следующим образом:
@{
Dictionary<string, MvcHtmlString> tagmap = new Dictionary<string, MvcHtmlString>() {
{ "HelpPage", Html.ActionLink("help page", "Help", "Home") }
};
}
и в других местах:
@this.Resource("Help", tagmap)
любые предложения по улучшению приветствуются