【问题标题】:Render HTML tags inside of HTML.ValidationMessageFor in MVC3在 MVC3 中的 HTML.ValidationMessageFor 内渲染 HTML 标签
【发布时间】:2015-10-07 20:20:45
【问题描述】:

我正在尝试将链接显示为字段验证消息的一部分。 我正在使用带有自定义错误消息的数据属性来设置它:

[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

我是新手,如果有人有任何建议,请发表。 谢谢!

【问题讨论】:

    标签: asp.net-mvc-3


    【解决方案1】:

    上面的代码不适用于客户端验证,因为它不会生成客户端验证所需的标签。

    这是对它的改进:

    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());
    }
    

    感谢您的原始帖子 - 它非常有帮助!

    【讨论】:

    • 刚刚发布了一个基于你的答案
    【解决方案2】:

    是的,这是可能的,但不能使用标准助手(ValidationSummaryValidationMessageFor)。如果你想实现这一点,你将不得不编写一个自定义助手来呈现这些消息。您可以查看 following post 示例,了解如何编写自定义的 ValidationSummary 帮助程序,该帮助程序不会将错误消息作为标准 HTML 编码。

    【讨论】:

      【解决方案3】:

      我使用的是 MVC4,所以我不能确定 MVC3。

      我能够插入&lt;br&gt; 标记(在我的情况下)的唯一方法是从 Jerode 的方法开始,但我还必须在消息字符串中放置一个标记并在剃刀中替换它。所以发送的消息是"Line 1[BR]Line2"。剃须刀是@Html.Raw(Html.ValidationMessageFor(x =&gt; Model.MyProperty).ToString().Replace("[BR]", "&amp;lt;br&amp;gt;"))

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        另一种方法是将验证项放在 Html.Raw 中。

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

        这不如建议的方法好,但应该可以完成您正在寻找的。​​p>

        【讨论】:

          【解决方案5】:

          基于@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合并属性来设置验证类来解决的。

          【讨论】:

            猜你喜欢
            • 2020-03-11
            • 2019-07-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-17
            • 2016-10-01
            • 2018-12-09
            • 2020-06-23
            相关资源
            最近更新 更多