2012-01-19 2 views
1

Я пытаюсь показать ссылку как часть сообщения проверки для поля. Я использую атрибуты данных с сообщениями об ошибках, чтобы установить его:Рендеринг HTML-тегов внутри HTML.ValidationMessageFor в MVC3

[Required(ErrorMessage = "Message <a href='#'>link</a>")] 
public string Field{ get; set; } 

Но когда он делает теги экранируются и буквально печатает:

Message <a href='#'>link</a> 

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

В случае, если кто заинтересован, вот как я достиг его

public static MvcHtmlString ValidationHTMLMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) 
{ 
    return ValidationHTMLMessageFor(helper, expression, (object)null); 
} 
public static MvcHtmlString ValidationHTMLMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) 
{ 
    return ValidationHTMLMessageFor(helper, expression, new RouteValueDictionary(htmlAttributes)); 
} 
public static MvcHtmlString ValidationHTMLMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) 
{ 
    string propertyName = ExpressionHelper.GetExpressionText(expression); 
    string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName)); 

    if (helper.ViewData.ModelState[name] == null || 
     helper.ViewData.ModelState[name].Errors == null || 
     helper.ViewData.ModelState[name].Errors.Count == 0) 
    { 
     return MvcHtmlString.Empty; 
    } 

    string errors = ""; 
    foreach (ModelError error in helper.ViewData.ModelState[name].Errors) 
    { 
     TagBuilder tag = new TagBuilder("span"); 
     tag.Attributes.Add("class", HtmlHelper.ValidationMessageCssClassName); 
     tag.MergeAttributes(htmlAttributes); 
     tag.Attributes.Add("data-valmsg-for", name); 
     tag.Attributes.Add("data-valmsg-replace", "true"); 

     var text = tag.ToString(TagRenderMode.StartTag); 
     text += error.ErrorMessage; 
     text += tag.ToString(TagRenderMode.EndTag); 
     errors += text; 
    } 

    return MvcHtmlString.Create(errors); 

} 

Спасибо Дарина указал мне в правильном направлении. Я также нашел это, что использовал в качестве шаблона Customize Html.ValidationMessageFor doesn't work in client side.

Я новичок в этом, поэтому, если у кого-то есть предложения, пожалуйста, напишите. Спасибо!

ответ

2

Да, это возможно, но не со стандартными помощниками (ValidationSummary и ValidationMessageFor). Вам нужно будет написать пользовательский помощник для отображения этих сообщений, если вы этого хотите. Вы можете взглянуть на following post на пример того, как написать пользовательский помощник ValidationSummary, который не кодирует HTML сообщения об ошибках как стандартные.

3

Этот код не работает с проверкой на стороне клиента, так как он не создает теги, необходимые для проверки на стороне клиента.

Вот улучшение на нем, что делает это:

public static MvcHtmlString ValidationHTMLMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) 
{ 
    string propertyName = ExpressionHelper.GetExpressionText(expression); 
    string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName)); 

    TagBuilder tag = new TagBuilder("span"); 
    tag.Attributes.Add("class", HtmlHelper.ValidationMessageCssClassName); 
    tag.MergeAttributes(htmlAttributes); 
    tag.Attributes.Add("data-valmsg-for", name); 
    tag.Attributes.Add("data-valmsg-replace", "true"); 
    var returnTag = new StringBuilder(tag.ToString(TagRenderMode.StartTag)); 

    if (helper.ViewData.ModelState[name] != null && 
     helper.ViewData.ModelState[name].Errors != null && 
     helper.ViewData.ModelState[name].Errors.Count > 0) 
    { 
    foreach (ModelError error in helper.ViewData.ModelState[name].Errors) 
    { 
     returnTag.Append(error.ErrorMessage); 
    } 
    } 
    returnTag.Append(tag.ToString(TagRenderMode.EndTag)); 
    return MvcHtmlString.Create(returnTag.ToString()); 
} 

Спасибо за оригинальный пост - это было очень полезно!

+0

Просто отправил ответ на ваш –

0

Другим подходом было бы просто поместить элемент проверки внутри Html.Raw.

@Html.Raw(Html.ValidationMessageFor(x => Model.MyProperty)) 

Это не так хорошо, как подход, как предложения, но должен выполнить то, что вы ищете.

1

Я использую MVC4, поэтому не могу сказать точно о MVC3.

Единственный способ, которым я смог вставить тег <br> (в моем случае), должен был начаться с метода Джедеда, но мне также пришлось поместить маркер в строку сообщения и заменить его в бритве. Поэтому отправленное сообщение было "Line 1[BR]Line2". Бритва была @Html.Raw(Html.ValidationMessageFor(x => Model.MyProperty).ToString().Replace("[BR]", "&lt;br&gt;"))

Надеюсь, что это поможет.

0

Опираясь на ответ от @shycohen:

public static MvcHtmlString HtmlValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null) 
    { 
     string propertyName = ExpressionHelper.GetExpressionText(expression); 
     string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName)); 

     TagBuilder tag = new TagBuilder("span"); 

     tag.Attributes.Add("data-valmsg-for", name); 
     tag.Attributes.Add("data-valmsg-replace", "true"); 

     if (htmlAttributes != null) 
     { 
      tag.MergeAttributes((IDictionary<string, object>)HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 
     } 

     tag.AddCssClass(HtmlHelper.ValidationMessageCssClassName); 

     var returnTag = new StringBuilder(tag.ToString(TagRenderMode.StartTag)); 

     if (helper.ViewData.ModelState[name] != null && 
      helper.ViewData.ModelState[name].Errors != null && 
      helper.ViewData.ModelState[name].Errors.Count > 0) 
     { 
      foreach (ModelError error in helper.ViewData.ModelState[name].Errors) 
      { 
       returnTag.Append(error.ErrorMessage); 
      } 
     } 

     returnTag.Append(tag.ToString(TagRenderMode.EndTag)); 

     return MvcHtmlString.Create(returnTag.ToString()); 
    } 

Параметр htmlAttributes теперь необязательна и передается как анонимный объект для более близкого матча ValidationMessageFor.

Другая проблема заключалась в невозможности добавления дополнительных классов через htmlAttributes, так как TagBuilder.MergeAttributes не объединяет значения атрибутов. Это решается путем использования TagBuilder.AddCssClassпосле слияния атрибутов для установки класса проверки.

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