如何从ASP.Net MVC modelState获取所有错误?

cho*_*bo2 430 asp.net-mvc modelstate

我想在不知道键值的情况下从modelState中获取所有错误消息.循环以获取ModelState包含的所有错误消息.

我怎样才能做到这一点?

Ore*_*ner 508

foreach (ModelState modelState in ViewData.ModelState.Values) {
    foreach (ModelError error in modelState.Errors) {
        DoSomethingWith(error);
    }
}
Run Code Online (Sandbox Code Playgroud)

另请参见如何在ASP.NET MVC中获取模型状态错误的集合?.

  • 很有帮助.请注意,在某些情况下,例如绑定失败和错误请求,将会有"Value.ErrorMessage"为空字符串的ModelState条目,而是"Value.Exception.Message". (20认同)
  • 错误很好但有时你也想要模型状态的键(即字段的名称).你可以通过将第一行更改为:'foreach(KeyValuePair <string,ModelState> kvp in htmlHelper.ViewData.ModelState){`并在其下面插入这一行:`var modelState = kvp.Value;`.你可以从`kvp.Key`获得密钥 (4认同)

mmu*_*lva 499

使用LINQ:

IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
Run Code Online (Sandbox Code Playgroud)

  • 修改为只返回IEnumerable <string>,只显示错误消息:: var allErrors = ModelState.Values.SelectMany(v => v.Errors.Select(b => b.ErrorMessage)); (63认同)
  • 这很棒,但不幸的是Watch/Immediate窗口不支持lambda's :( (6认同)
  • @ hakam-fostok @ jb06你是对的.键入`List <string> errors = new List <string>()`而不是`var errors = new List <string>()`实际上是浪费时间,但编写`IEnumerable <ModelError> allErrors = ModelState.Values. SelectMany(v => v.Errors);`,返回类型不是很清楚,在可读性方面确实更大.(即使视觉工作室可以通过鼠标悬停给你) (6认同)
  • 是! 我(你,任何人)需要"使用System.Linq;" 前几名.否则,您会收到消息"值不包含Select many的定义".在我的情况下它丢失了. (3认同)
  • 为什么在地狱中使用var ?????? 你不能写“ IEnumerable &lt;ModelError&gt;”代替吗? (2认同)
  • @JB06 键入所有变量类型将节省阅读我们代码的人的时间,因此它节省了时间。 (2认同)

Dun*_*unc 185

在LINQ版本的基础上,如果要将所有错误消息加入一个字符串:

string messages = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));
Run Code Online (Sandbox Code Playgroud)

  • 另一个选项是执行以下操作:ModelState.Values.SelectMany(x => x.Errors).Select(x => x.ErrorMessage).JoinString(";"); (5认同)
  • 或... ModelState.Values.SelectMany(O => O.Errors).Select(O => O.ErrorMessage).Aggregate((U,V)=> U +","+ V) (5认同)
  • @Tod,是IEnumerable.JoinString()你自己的扩展方法吗?请参见http://stackoverflow.com/q/4382034/188926 (3认同)
  • 嘿Dunc-是的,我怀疑我已将该扩展方法添加到我的代码库中,并且忘记了它,然后认为它是一种框架方法,哈哈( (2认同)
  • 当您使用web api并返回IHttpActionResult结果时,这非常有用.所以,你可以这样做:返回BadRequest(消息); 谢谢,Dunc! (2认同)
  • @JustJohn 键名称:`ModelState.SelectMany(x =&gt; x.Value.Errors.Select(y =&gt; $"{x.Key}: {y.ErrorMessage}"))` (2认同)

Yas*_*ser 31

我能用一点LINQ做到这一点,

public static List<string> GetErrorListFromModelState
                                              (ModelStateDictionary modelState)
{
      var query = from state in modelState.Values
                  from error in state.Errors
                  select error.ErrorMessage;

      var errorList = query.ToList();
      return errorList;
}
Run Code Online (Sandbox Code Playgroud)

上述方法返回验证错误列表.

进一步阅读:

如何从ASP.NET MVC中的ModelState读取所有错误


Sim*_*ver 15

在调试过程中,我发现在每个页面的底部放置一个表来显示所有ModelState错误很有用.

<table class="model-state">
    @foreach (var item in ViewContext.ViewData.ModelState) 
    {
        if (item.Value.Errors.Any())
        { 
        <tr>
            <td><b>@item.Key</b></td>
            <td>@((item.Value == null || item.Value.Value == null) ? "<null>" : item.Value.Value.RawValue)</td>
            <td>@(string.Join("; ", item.Value.Errors.Select(x => x.ErrorMessage)))</td>
        </tr>
        }
    }
</table>

<style>
    table.model-state
    {
        border-color: #600;
        border-width: 0 0 1px 1px;
        border-style: solid;
        border-collapse: collapse;
        font-size: .8em;
        font-family: arial;
    }

    table.model-state td
    {
        border-color: #600;
        border-width: 1px 1px 0 0;
        border-style: solid;
        margin: 0;
        padding: .25em .75em;
        background-color: #FFC;
    }
 </style>
Run Code Online (Sandbox Code Playgroud)


Ala*_*ald 12

正如我发现在目前为止给出的答案中遵循了建议,您可以在没有设置错误消息的情况下发生异常,因此要捕获所有问题,您需要同时获取ErrorMessage和Exception.

String messages = String.Join(Environment.NewLine, ModelState.Values.SelectMany(v => v.Errors)
                                                           .Select( v => v.ErrorMessage + " " + v.Exception));
Run Code Online (Sandbox Code Playgroud)

或作为一种延伸方法

public static IEnumerable<String> GetErrors(this ModelStateDictionary modelState)
{
      return modelState.Values.SelectMany(v => v.Errors)
                              .Select( v => v.ErrorMessage + " " + v.Exception).ToList();

}
Run Code Online (Sandbox Code Playgroud)


小智 9

此代码片段也很有用,它为您提供一个包含错误消息的列表。

var errors = ModelState.Values.SelectMany(x => x.Errors.Select(c => c.ErrorMessage)).ToList();


jam*_*ock 8

如果有人想要返回Model属性的名称,以便在强类型视图中绑定错误消息.

List<ErrorResult> Errors = new List<ErrorResult>();
foreach (KeyValuePair<string, ModelState> modelStateDD in ViewData.ModelState)
{
    string key = modelStateDD.Key;
    ModelState modelState = modelStateDD.Value;

    foreach (ModelError error in modelState.Errors)
    {
        ErrorResult er = new ErrorResult();
        er.ErrorMessage = error.ErrorMessage;
        er.Field = key;
        Errors.Add(er);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您实际上可以将错误与引发错误的字段联系起来.


Jiv*_*ari 7

任何人都在寻找 asp.net core 3.1。答案包括键(字段名称)。大多数其他答案仅包含错误。

我发现这就是 [ApiController] 返回的

 Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>();

                foreach (KeyValuePair<string, ModelStateEntry> kvp in ViewData.ModelState)
                {
                    string key = kvp.Key;
                    ModelStateEntry entry = kvp.Value;

                    if (entry.Errors.Count > 0)
                    {
                        List<string> errorList = new List<string>();
                        foreach (ModelError error in entry.Errors)
                        {
                            errorList.Add(error.ErrorMessage);
                        }

                        errors[key] = errorList;
                    }
                }

                return  new JsonResult(new {Errors = errors});
Run Code Online (Sandbox Code Playgroud)


Cod*_*ist 5

以防万一有人需要它,我在我的项目中使用了以下静态类

用法示例:

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}
Run Code Online (Sandbox Code Playgroud)

用途:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using WebGrease.Css.Extensions;
Run Code Online (Sandbox Code Playgroud)

类:

public static class ModelStateErrorHandler
{
    /// <summary>
    /// Returns a Key/Value pair with all the errors in the model
    /// according to the data annotation properties.
    /// </summary>
    /// <param name="errDictionary"></param>
    /// <returns>
    /// Key: Name of the property
    /// Value: The error message returned from data annotation
    /// </returns>
    public static Dictionary<string, string> GetModelErrors(this ModelStateDictionary errDictionary)
    {
        var errors = new Dictionary<string, string>();
        errDictionary.Where(k => k.Value.Errors.Count > 0).ForEach(i =>
        {
            var er = string.Join(", ", i.Value.Errors.Select(e => e.ErrorMessage).ToArray());
            errors.Add(i.Key, er);
        });
        return errors;
    }

    public static string StringifyModelErrors(this ModelStateDictionary errDictionary)
    {
        var errorsBuilder = new StringBuilder();
        var errors = errDictionary.GetModelErrors();
        errors.ForEach(key => errorsBuilder.AppendFormat("{0}: {1} -", key.Key,key.Value));
        return errorsBuilder.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*eld 5

仅输出错误消息本身对我来说还不够,但这确实可以解决问题。

var modelQuery = (from kvp in ModelState
                  let field = kvp.Key
                  let state = kvp.Value
                  where state.Errors.Count > 0
                  let val = state.Value?.AttemptedValue ?? "[NULL]"

                  let errors = string.Join(";", state.Errors.Select(err => err.ErrorMessage))
                  select string.Format("{0}:[{1}] (ERRORS: {2})", field, val, errors));

Trace.WriteLine(string.Join(Environment.NewLine, modelQuery));
Run Code Online (Sandbox Code Playgroud)


小智 5

<div class="text-danger" style="direction:rtl" asp-validation-summary="All"></div>
Run Code Online (Sandbox Code Playgroud)

只需使用 asp-validation-summary 标签帮助程序