2016-03-22 4 views
1

У меня есть метод, который захватывает локализацию данной строки и возвращает ее. Этот метод вызывается методом расширения HtmlHelper, так что он доступен из представлений Razor. Однако иногда мы также используем его в контроллерах и других местах, отличных от Razor, и поэтому у нас есть «внутренний» метод.Создание HTML из класса, отличного от MVC

Теперь, для отладки, я хотел бы обернуть возвращенную, локализованную (или, возможно, не) строку в некоторый HTML (что-то вроде <span class="localized">Returned text</span>). Тем не менее, если я пишу

return string.Format("<span class=\"localized\">{0}</span>", text); 

то оказывается страница включает < и > символы, как если бы они были HTML-кодировке, поэтому выход является поддельным.

Я не могу, конечно, назвать HtmlHelper.Raw(string s), отчасти потому, что я не знаю, как создать HtmlHelper из-за контроллер MVC, а затем, поскольку она возвращает IHtmlString, который не является присваиваемым string.

Если я звоню HttpUtility.HtmlEncode(string s), текст дважды кодируется, а на отображаемой странице отображается &lt;span class&eq;&quot;....

Что мне делать, чтобы иметь строку, которая отображает HTML в представлении?


EDIT

Вот код, от Helper статического класса (все методы расширения работы, за исключением того, что они ведут себя неправильно):

public static string localize(string textId) 
{ 
    string ret = ""; 

    // Query to obtain the localized string, 
    // or to obtain a fallback in case there are issues 
    // (missing localization, wrong id...) 
    // In the end, ret is filled with the output string 

#if !OFFICIAL 
    ret = string.Format("<span class=\"localized\" title=\"{1}\">{0}</span>", ret, expression); 
#endif 

    return ret; 
} 

public static string localize(this HtmlHelper htmlhelper, string expression) 
{ 
    return trad(textId); 
} 
+0

Где ваш 'метод string.Format' вызывается из? – Lee

+0

'IHtmlString.ToString()' возвращает 'string' –

+0

@Lee из внутреннего метода, который может вызываться методом расширения HtmlHelper или из других мест. – Simone

ответ

2

Учитывая, что вы прокомментировали вы хотите сделать

@Html.localize("textId") 

outpu t элемент HTML, решение кажется очевидным: с возвратным типом string это просто невозможно по дизайну. Поэтому измените свой метод, чтобы не возвращать string.

Вы уже нашли, что в принципе можете использовать HtmlHelper.Raw, который возвращает IHtmlString, за исключением того, что IHtmlString не может быть назначен string. Если вы измените свой тип возврата на IHtmlString, проблема будет решена.

+0

Правда, но есть еще один момент. Некоторые из моих локализованных строк имеют заполнители, потому что они должны быть переданы в 'string.Format()'. 'string.Format()', конечно, принимает только строки, а не 'IHtmlString', и если я возвращаю' IHtmlString', тогда вызывается 'ToString()', тогда преимущество теряется, поэтому я получаю некоторые текстовые строки, все еще показывающие как если бы они были закодированы. Предложения для этого? – Simone

+1

@ Симон Я не думаю, что это может поместиться в дизайне, который у вас есть сейчас. Вам нужно заново подумать о своем дизайне. Но если у вас теперь есть '@ string.Format (Html.localize (" textId ")," param1 "," param2 ")', вы должны иметь возможность изменить это без особых усилий на '@ Html.localize (" textId "," param1 "," param2 ")', где вы позволяете 'Html.localize' вызывать' string.Format' перед тем, как наполнить результат элементом ''. – hvd

+0

Хорошее предложение @hvd, я надеялся, что смогу это избежать, но я думаю, мне придется жить с этим. Я пытаюсь это прямо сейчас. – Simone

1

Razor render string как есть. Вы должны использовать HtmlString для методов расширения с разметкой.

Если объявить метод следующим образом:

public static HtmlString localize(this HtmlHelper htmlhelper, string expression) 
{ 
    return new HtmlString(trad(textId)); 
} 

Вы WIIL быть в состоянии использовать свой собственный метод расширения, как

@Html.localize('your string') 

выдаваемого в качестве правильной разметки

+0

Правда, но есть еще один момент. Некоторые из моих локализованных строк имеют заполнители, потому что они должны быть переданы в 'string.Format()'. 'string.Format()', конечно, принимает только строки, а не 'IHtmlString', и если я возвращаю' IHtmlString', тогда вызывается 'ToString()', тогда преимущество теряется, поэтому я получаю некоторые текстовые строки, все еще показывающие как если бы они были закодированы. Предложения для этого? – Simone

2

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

  • Неадресный метод Localize должен только попытаться вернуть локализованный string. Добавление тегов html не связано с этим методом.(Вы можете добавить теги html и здесь без каких-либо проблем, потому что в следующем методе мы используем HtmlString для создания вывода.)
  • Вспомогательный метод должен использовать предыдущий метод, а затем добавлять теги html, которые вам нужны, и, наконец, вернуть HtmlString.

Код:

public static class Extensions 
{ 
    public static string Localize(string exp) 
    { 
     var ret = exp; 
     try 
     { 
      //try to apply localized version of exp, for example: 
      ret = exp + "_Localized"; 
     } 
     catch(Exception ex) 
     { 
      //Log ex 
     } 

     return ret; 
    } 

    public static IHtmlString Localize(this HtmlHelper htmlhelper, string exp) 
    { 
     var ret = string.Format("<span class=\"localized\" title=\"{0}\">{1}</span>", 
           exp, Localize(exp)); 
     return new HtmlString(ret); 
    } 
} 
+0

Это решит некоторые проблемы, но это не то, что мне нужно, потому что 1) Мне нужен пролет точно для того, чтобы отслеживать, что во время локализации произошли ошибки, о которых «Локализация» помощника ничего не знает, и 2) это не будет отслеживать _all_ локализации, которые я делаю. Если я вызову метод из контроллера (а не через помощник), то никаких дополнительных действий не будет. – Simone

+0

Нет проблем, вы можете вернуть html не-хелперу, это всего лишь рекомендация о разделении проблем. Это будет работать так, как ожидалось, потому что я использую 'HtmlString' как вывод. –

+0

Правда, но есть еще один момент. Некоторые из моих локализованных строк имеют заполнители, потому что они должны быть переданы в 'string.Format()'. 'Строка.Format() ', конечно, принимает только строки, а не' IHtmlString', и если я возвращаю 'IHtmlString', тогда вызывается' ToString() ', тогда преимущество теряется, поэтому я заканчиваю тем, что некоторые текстовые строки все еще отображаются так, как будто они были закодированы. Предложения для этого? – Simone

Смежные вопросы