【问题标题】:How to display multiple validation errors with @Html.ValidationMessageFor?如何使用@Html.ValidationMessageFor 显示多个验证错误?
【发布时间】:2011-11-22 07:08:30
【问题描述】:

我可以看到我的ModelState.Values[x].Errors 正确填充了单个属性的两个验证错误。

如果我在我的视图中使用@Html.ValidationSummary(),它会正确显示这两个错误....尽管在页面顶部,而不是在有问题的输入旁边。

使用@Html.ValidationMessageFor(model => model.MyProperty) 只显示该属性的第一个错误

如何在适当的输入旁边显示这两个错误?

【问题讨论】:

    标签: asp.net-mvc-3 validation


    【解决方案1】:

    一种解决方案是在 HtmlHelper 上实现您自己的扩展方法,该方法与默认的 ValidationMessageFor 行为不同。下面的示例@Html.ValidationMessagesFor 方法将连接多个在服务器端 验证期间添加到ModelState 的错误消息(仅限)。

    public static MvcHtmlString ValidationMessagesFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
    {
        var propertyName = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).PropertyName;
        var modelState = htmlHelper.ViewData.ModelState;
    
        // If we have multiple (server-side) validation errors, collect and present them.
        if (modelState.ContainsKey(propertyName) && modelState[propertyName].Errors.Count > 1)
        {
            var msgs = new StringBuilder();
            foreach (ModelError error in modelState[propertyName].Errors)
            {
                msgs.AppendLine(error.ErrorMessage);
            }
    
            // Return standard ValidationMessageFor, overriding the message with our concatenated list of messages.
            return htmlHelper.ValidationMessageFor(expression, msgs.ToString(), htmlAttributes as IDictionary<string, object> ?? htmlAttributes);
        }
    
        // Revert to default behaviour.
        return htmlHelper.ValidationMessageFor(expression, null, htmlAttributes as IDictionary<string, object> ?? htmlAttributes);
    }
    

    如果您要跨属于您的模型的集合应用自定义业务验证(例如,交叉检查总计)或检查整个模型,这将非常有用。

    一个使用这个的例子,其中一个 Order.LineItems 的集合在服务器端被验证:

    @using MyHtmlHelperExtensions    // namespace containing ValidationMessagesFor
    @using (Html.BeginForm())
    {
        @Html.LabelFor(m => m.LineItems)
        <ul>
            @Html.EditorFor(m => m.LineItems)
        </ul>
        @Html.ValidationMessagesFor(m => m.LineItems)
    }
    

    【讨论】:

    • 不错的解决方案。这适用于带有视图模型的嵌套视图吗?我必须添加以下内容:var relativePropertyName = ExpressionHelper.GetExpressionText(expression);var propertyName = String.Format("{0}{2}{1}", htmlHelper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix, relativePropertyName, (String.IsNullOrWhiteSpace(relativePropertyName) ? String.Empty : "."));
    • 让它与嵌套视图一起工作的更简单方法是:propertyName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName)
    • 优秀的答案,它的工作原理。除了我的两个错误都在同一行之外。我需要每条错误消息都在它自己的行上。例如,在
      之间有一个标签
    • @theB3RV 或者你可以使用white-space: pre-wrap; css。
    【解决方案2】:

    Dave A-W 提供的答案基本上是正确的,但并非在所有情况下都有效。为了获得正确的属性名称,MVC 3 的源代码使用:

    var propertyName = ExpressionHelper.GetExpressionText(expression);
    

    这会处理表单数据中的所有前缀

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 2020-03-10
      • 2012-08-24
      • 1970-01-01
      相关资源
      最近更新 更多