【问题标题】:Newline in a ValidationMessageValidationMessage 中的换行符
【发布时间】:2012-10-06 05:41:38
【问题描述】:

我正在测试 null 的事物列表。每次找到一个,我都会将它保存在一个数组中,以便在验证消息中实现它。

我想要的输出如下所示:

字段 1 为必填项
字段 4 为必填项
等等……

但我似乎无法开始新行。

现在,它看起来像这样:

字段 1 为必填项 字段 4 为必填项

有人知道如何实现吗?

编辑:

控制器:

IDictionary<int, String> emptyFields = new Dictionary<int, String>();

foreach (Something thing in AnotherThing.Collection)
{
    if (thing.Property == null)
        emptyFields.add(thing.Index, thing.Name);                   
}

if (emptyFields.Any())
    throw new CustomException() { EmptyFields = emptyFields };

这里处理这个异常:

catch (CustomException ex)
{                   
    ModelState.AddModelError("file", ex.GetExceptionString());
    return View("theView");
}    

自定义异常:

public class CustomException: Exception
{
    public IDictionary<int,String> EmptyFields { get; set; }
    public override String Label { get { return "someLabel"; } }
    public override String GetExceptionString()
    {
        String msg = "";
        foreach (KeyValuePair<int,String> elem in EmptyFields)
        {
            msg += "row: " + (elem.Key + 1).ToString() + " column: " + elem.Value + "<br/>";      
        }
        return msg;        
    }
}

查看:

<span style="color: #FF0000">@Html.Raw(Html.ValidationMessage("file").ToString())</span>

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 newline line-breaks validationmessage


    【解决方案1】:

    试试这个

    在每条错误消息后附加
    标签并使用 Html.Raw() 方法显示您的内容 Html.Raw 将解码 HtmlContent。

    you message like 
     Field 1 is required <br/>Field 4 is required<br/> 
    
    In View
    
    Html.Raw("Yore Error Message")
    

    【讨论】:

    • 它对我不起作用。我应该提到我正在自定义异常中构造消息。我会更新我的帖子。
    【解决方案2】:

    您是否在验证摘要中显示它们?我认为它不支持用于换行等的 html。我将创建一个基于显示 html 的验证摘要的自定义 html 助手。

    这同样适用于验证消息,因此可能需要为此创建自定义助手

    【讨论】:

      【解决方案3】:

      您需要编写一个自定义助手来实现这一点。内置的 ValidationMessageFor 助手会自动对值进行 HTML 编码。这是一个例子:

      public static class ValidationMessageExtensions
      {
          public static IHtmlString MyValidationMessageFor<TModel, TProperty>(
              this HtmlHelper<TModel> htmlHelper, 
              Expression<Func<TModel, TProperty>> ex
          )
          {
              var htmlAttributes = new RouteValueDictionary();
              string validationMessage = null;
              var expression = ExpressionHelper.GetExpressionText(ex);
              var modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
              var formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;
              if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName) && formContext == null)
              {
                  return null;
              }
      
              var modelState = htmlHelper.ViewData.ModelState[modelName];
              var modelErrors = (modelState == null) ? null : modelState.Errors;
              var modelError = (((modelErrors == null) || (modelErrors.Count == 0)) 
                  ? null 
                  : modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]);
      
              if (modelError == null && formContext == null)
              {
                  return null;
              }
      
              var builder = new TagBuilder("span");
              builder.MergeAttributes(htmlAttributes);
              builder.AddCssClass((modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);
      
              if (!String.IsNullOrEmpty(validationMessage))
              {
                  builder.InnerHtml = validationMessage;
              }
              else if (modelError != null)
              {
                  builder.InnerHtml = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState);
              }
      
              if (formContext != null)
              {
                  bool replaceValidationMessageContents = String.IsNullOrEmpty(validationMessage);
                  builder.MergeAttribute("data-valmsg-for", modelName);
                  builder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
              }
      
              return new HtmlString(builder.ToString(TagRenderMode.Normal));
          }
      
          private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
          {
              if (!String.IsNullOrEmpty(error.ErrorMessage))
              {
                  return error.ErrorMessage;
              }
              if (modelState == null)
              {
                  return null;
              }
      
              var attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
              return string.Format(CultureInfo.CurrentCulture, "Value '{0}' not valid for property", attemptedValue);
          }
      }
      

      然后:

      public class MyViewModel
      {
          [Required(ErrorMessage = "Error Line1<br/>Error Line2")]
          public string SomeProperty { get; set; }
      }
      

      在视图中:

      @model MyViewModel
      @using (Html.BeginForm())
      {
          @Html.EditorFor(x => x.SomeProperty)
          @Html.MyValidationMessageFor(x => x.SomeProperty)
          <button type="submit">OK</button>
      }
      

      如果您想在 ValidationSummary 中显示错误消息,您还可以编写一个不会对错误消息进行 HTML 编码的自定义助手,就像我在 this post 中显示的那样。

      【讨论】:

      • 我发现了一些关于扩展的线程。但要完成如此基本的事情,感觉就像是一项艰巨的工作。我只是想检查一下我是否还有其他方法。
      • 你说 50 行代码工作量很大吗?哇。那么你是如何编写真正的代码的:-)
      • 写一个
        ...有点;)这并不是我不想这样做。我认为一个好的程序员应该“保持简单”。获得换行符的 50 行代码感觉并不像保持简单。这就是为什么我想检查是否有其他方法。
      • @S4NDERR,别再怀疑了——微软没有神。他们无法实现我们可能想到的每一个功能。为了实现一个特性,需要为这个特性编写规范,它需要被实现、测试、文档化、集成到现有的框架中、需要做回归测试等等......你甚至意识到有多少在 .NET 框架中实现一个功能需要成本吗?如果他们实现了我们想要的所有功能,那么我们将永远不会看到新版本的出现。
      • 我不确定这一点,但不是将标签转换为字符串功能,而不是让它们保持原始状态吗?让我们顺其自然吧,因为我感受到了很多敌意。
      【解决方案4】:

      你可以用这一个班轮做到这一点:

      @Html.Raw(HttpUtility.HtmlDecode(Html.ValidationMessageFor(m => m.Property).ToHtmlString()))
      

      【讨论】:

      • +1 聪明,这非常适合我和作者正在寻找的简单而简短的修复。
      • 我已经将它用于像这样的验证摘要 @if (Html.ValidationSummary(true) != null) { @Html.Raw(HttpUtility.HtmlDecode(Html.ValidationSummary(true).ToString() )); }
      • +1 这应该是正确的答案!我同意@sander 的观点,没有人愿意为了换行就添加 50 行代码!
      【解决方案5】:

      我所做的就是将它们放在一个 div 中

             <div class="Errors">
      
              @Html.ValidationMessageFor(m => m.Name)<br/>
              @Html.ValidationMessageFor(m => m.LName)<br />
            </div>
      

      然后创建一个类

           .Errors {
                color: red;
                font-size: 10px;
                font-weight: bold;
                }
      

      但是如果你想做一个多行错误,那么 Leinel 提到的是最好的方法。我把它们捆绑在一起的原因是一些用户不会看到长表单的错误,他们会开始给我们打电话.. ^^,

      【讨论】:

        【解决方案6】:

        如果有人正在寻找它,以下是如何为验证摘要执行此操作:

        @Html.Raw(HttpUtility.HtmlDecode(Html.ValidationSummary(true).ToHtmlString()))
        

        【讨论】:

          【解决方案7】:

          感谢我参加这个聚会有点晚了,但刚刚遇到这个问题并且使用普通的旧 css 也很有效:

          <style>
              .field-validation-error::after {
                  content: "\a";
                  white-space: pre;
              }
          </style>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-07-08
            • 1970-01-01
            • 2020-08-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多