2015-04-24 2 views
0

Используя MVC и Razor, я хочу создать метку для поля, содержащего HTML, а именно гиперссылку. Однако, когда я использую метод Html.LabelFor(), весь HTML кодируется на выходе.Сгенерировать метку с содержимым HTML

Этот скриншот показывает желаемый результат и то, что на самом деле MVC выводит вместо:

enter image description here

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

Мои ViewModel:

[DisplayName("I accept the <a href=\"/Terms &amp; conditions\">Terms &amp; conditions</a>")] 
public bool AcceptedTermsAndConditions { get; set; } 

Мое мнение:

@Html.EditorFor(m => m.AcceptedTermsAndConditions) 
@Html.LabelFor(m => m.AcceptedTermsAndConditions) 

Я также попытался непосредственно передать содержимое в качестве параметра "LabelText", без успеха:

@Html.LabelFor(m => m.AcceptedTermsAndConditions, "I accept the <a href=\"/Terms &amp; conditions\">Terms &amp; conditions</a>") 
+0

Почему вы не просто использовать '[DisplayName («Я принимаю»)]' и на ваш взгляд месте '' тег, как обычно право после '@ Html.LabelFor'? EDIT: Я предполагаю, что это вряд ли для этого якоря часто меняет URL. – Esteban

+2

@Esteban Потому что это взломать? Перемещение ссылки с метки вызывает всевозможные проблемы: от локализации до разных языков, на которых ссылка может появляться в середине текста, при проблемах, когда я изменил внешний вид метки с помощью CSS позже. Я искал правильное решение для общего дела. Существует причина, по которой тег метки допускает содержимое HTML. – magnattic

+0

достаточно справедливо. похоже, что вы можете использовать '@ Html.Raw' для отображения вашего' LabelFor (m => m.AcceptedTermsAndConditions) '. Ты это пробовал? – Esteban

ответ

-1

попытайтесь использовать это:

[DisplayName("I accept the <a href='Terms &amp; conditions'>Terms &amp; conditions</a>")] 
+1

Как это отличается от того, что я делал, кроме изменения кавычек? Я не понимаю, почему это работает, когда LabelFor() кодирует весь HTML. – magnattic

+0

Не работает, как подозревали. – magnattic

0

У меня есть. Таким образом, вместо

@Html.LabelFor(m => m.AcceptedTermsAndConditions) 

использования

Html.GetDisplayName(x => x.AcceptedTermsAndConditions) 
+1

Я уже думал об этом, но это не то же самое, что LabelFor(). Таким образом, мне придется окружить это вручную меткой и установить атрибут 'for =" AcceptedTermsAndConditions "с« магической строкой ». Главное преимущество LabelFor заключается в том, что он заботится об атрибуте for для вас, устанавливая его на тот же идентификатор, что и тег ввода. – magnattic

+0

Hoh! что было интересно @ Html.Raw (@ HttpUtility.HtmlDecode ( ) html.LabelFor (x => x.AcceptedTermsAndConditions) .ToString())) – Yuri

0

Не симпатичной, но решение:

@Html.Raw(@HttpUtility.HtmlDecode(Html.LabelFor(x=>x.AcceptedTermsAndConditions).ToString())) 
1

Я закончил тем, что писал мой собственный метод HtmlHelper на основе декомпилированных источников Html.LabelFor():

public static IHtmlString HtmlLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText = null, object htmlAttributes = null) 
{ 
    string str = labelText; 
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
    var htmlFieldName = ExpressionHelper.GetExpressionText(expression); 
    if (str == null) 
    { 
     string displayName = metadata.DisplayName; 
     if (displayName == null) 
     { 
      string propertyName = metadata.PropertyName; 
      str = propertyName ?? htmlFieldName.Split(new[] {'.'}).Last(); 
     } 
     else 
     { 
      str = displayName; 
     } 
    } 
    string innerHtml = str; 
    if (string.IsNullOrEmpty(innerHtml)) 
     return MvcHtmlString.Empty; 
    var tagBuilder = new TagBuilder("label"); 
    tagBuilder.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName))); 
    tagBuilder.InnerHtml = innerHtml; 
    tagBuilder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), true); 
    return new MvcHtmlString(tagBuilder.ToString(TagRenderMode.Normal)); 
} 

Основное изменение, которое я использую

tagBuilder.InnerHtml = .. 

вместо оригинального

tagBuilder.SetInnerText(..) 

Таким образом, при условии, LabelText не заканчивается тем, что HTML-кодирования.

Использование для моего случая это:

@Html.HtmlLabelFor(m => m.AcceptedTermsAndConditions)