如何在ASP.NET MVC中收集模型状态错误?


145

如何在视图中收集错误?

我不想使用HTML Helper验证摘要或验证消息。相反,我想检查是否有错误,是否有错误以特定格式显示。另外,在输入控件上,我想检查特定的属性错误并将类添加到输入中。

PS我正在使用Spark View Engine,但想法应该是相同的。

所以我想我可以做...

<if condition="${ModelState.Errors.Count > 0}">
  DispalyErrorSummary()
</if>

....and also...

<input type="text" value="${Model.Name}" 
       class="?{ModelState.Errors["Name"] != string.empty} error" />

....

或类似的东西。

更新

我的最终解决方案如下所示:

<input type="text" value="${ViewData.Model.Name}" 
       class="text error?{!ViewData.ModelState.IsValid && 
                           ViewData.ModelState["Name"].Errors.Count() > 0}" 
       id="Name" name="Name" />

如果此属性有错误,则仅添加错误css类。


Answers:


210
<% ViewData.ModelState.IsValid %>

要么

<% ViewData.ModelState.Values.Any(x => x.Errors.Count >= 1) %>

对于特定的财产...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection

1
ModelState属性为字典类型,以获取传递键名ViewData.ModelState [“ Name”]的错误

如果没有名称为“ Property”的键,则有关“ ViewData.ModelState [“ Property”]。Errors”的操作会抛出空引用异常吗?在读取错误之前先在ViewData.ModelState [“ Property”]上检查null是否会更好?
David Hollowell-MSFT 2012年

@DaveH是的,你应该完全检查它是否存在第一
亚历克斯·莱曼

61

要从ModelState中获取错误,请使用以下Linq:

var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);

2
如果没有指定名称的键,这会引发null引用异常吗?在读取错误之前先在ViewData.ModelState [key]上检查null是否会更好?
David Hollowell-MSFT 2012年

5
因为我们从迭代this.ModelState.Keys开始,所以我看不到KeyNotFoundException的可能性。我认为支票过大。
克里斯·麦肯齐


28

这将为您提供一个字符串,其中包含所有逗号分隔的错误

string validationErrors = string.Join(",",
                    ModelState.Values.Where(E => E.Errors.Count > 0)
                    .SelectMany(E => E.Errors)
                    .Select(E => E.ErrorMessage)
                    .ToArray());

这是我在整个列表中发现的唯一可以实际打印出错误的内容!谢谢
杰米

6

谢谢乍得!为了显示与密钥相关的所有错误,这是我想到的。由于某种原因,基本Html.ValidationMessage帮助器仅显示与该键关联的第一个错误。

    <%= Html.ShowAllErrors(mykey) %>

HtmlHelper:

    public static String ShowAllErrors(this HtmlHelper helper, String key) {
        StringBuilder sb = new StringBuilder();
        if (helper.ViewData.ModelState[key] != null) {
            foreach (var e in helper.ViewData.ModelState[key].Errors) {
                TagBuilder div = new TagBuilder("div");
                div.MergeAttribute("class", "field-validation-error");
                div.SetInnerText(e.ErrorMessage);
                sb.Append(div.ToString());
            }
        }
        return sb.ToString();
    }

6

从上面汇总了几个答案,这就是我最终使用的内容:

var validationErrors = ModelState.Values.Where(E => E.Errors.Count > 0)
    .SelectMany(E => E.Errors)
    .Select(E => E.ErrorMessage)
    .ToList();

validationErrors最终是一个List<string>包含每个错误消息的。从那里开始,使用该列表即可轻松完成所需的操作。

在此处输入图片说明


2

这是VB。

Dim validationErrors As String = String.Join(",", ModelState.Values.Where(Function(E) E.Errors.Count > 0).SelectMany(Function(E) E.Errors).[Select](Function(E) E.ErrorMessage).ToArray())

0

如果您不知道是什么属性导致了错误,则可以使用反射遍历所有属性:

public static String ShowAllErrors<T>(this HtmlHelper helper) {
    StringBuilder sb = new StringBuilder();
    Type myType = typeof(T);
    PropertyInfo[] propInfo = myType.GetProperties();

    foreach (PropertyInfo prop in propInfo) {
        foreach (var e in helper.ViewData.ModelState[prop.Name].Errors) {
            TagBuilder div = new TagBuilder("div");
            div.MergeAttribute("class", "field-validation-error");
            div.SetInnerText(e.ErrorMessage);
            sb.Append(div.ToString());
        }
    }
    return sb.ToString();
}

其中T是“ ViewModel”的类型。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.