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

发布于 2024-08-03 12:25:01 字数 83 浏览 5 评论 0原文

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

我该怎么做?

I want to get all the error messages out of the modelState without knowing the key values. Looping through to grab all the error messages that the ModelState contains.

How can I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

尬尬 2024-08-10 12:25:01

使用 LINQ

IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);

Using LINQ:

IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
昔梦 2024-08-10 12:25:01
foreach (ModelState modelState in ViewData.ModelState.Values) {
    foreach (ModelError error in modelState.Errors) {
        DoSomethingWith(error);
    }
}

另请参阅如何做我得到了 ASP.NET MVC 中模型状态错误的集合?

foreach (ModelState modelState in ViewData.ModelState.Values) {
    foreach (ModelError error in modelState.Errors) {
        DoSomethingWith(error);
    }
}

See also How do I get the collection of Model State Errors in ASP.NET MVC?.

辞旧 2024-08-10 12:25:01

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

string messages = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));

Building on the LINQ verison, if you want to join all the error messages into one string:

string messages = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));
咽泪装欢 2024-08-10 12:25:01

我可以使用一点 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;
}

上面的方法返回验证错误列表。

进一步阅读:

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

I was able to do this using a little 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;
}

The above method returns a list of validation errors.

Further Reading :

How to read all errors from ModelState in ASP.NET MVC

孤云独去闲 2024-08-10 12:25:01

在调试过程中,我发现在每个页面的底部放置一个表格来显示所有 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>

During debugging I find it useful to put a table at the bottom of each of my pages to show all ModelState errors.

<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>
暗地喜欢 2024-08-10 12:25:01

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

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

或作为扩展方法

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

}

As I discovered having followed the advice in the answers given so far, you can get exceptions occuring without error messages being set, so to catch all problems you really need to get both the ErrorMessage and the Exception.

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

or as an extension method

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

}
方觉久 2024-08-10 12:25:01

如果有人想要返回模型属性的名称以将错误消息绑定到强类型视图中。

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

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

In case anyone wants to return the Name of the Model property for binding the error message in a strongly typed view.

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

This way you can actually tie the error in with the field that threw the error.

梦魇绽荼蘼 2024-08-10 12:25:01

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

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

This code snippet is useful too and give you a List that contains of Error Messges.

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

清晨说晚安 2024-08-10 12:25:01

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

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

Outputting just the Error messages themselves wasn't sufficient for me, but this did the trick.

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));
千纸鹤带着心事 2024-08-10 12:25:01

任何人都在寻找 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});

Anybody looking for asp.net core 3.1. The answer includes key (field name). Most of other answers include only errors.

I found that this is what [ApiController] returns

 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});
甩你一脸翔 2024-08-10 12:25:01

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

使用示例:

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}

用途:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using WebGrease.Css.Extensions;

类:

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

For just in case someone need it i made and use the following static class in my projects

Usage example:

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}

Usings:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using WebGrease.Css.Extensions;

Class:

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();
    }
}
白首有我共你 2024-08-10 12:25:01
<div class="text-danger" style="direction:rtl" asp-validation-summary="All"></div>

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

<div class="text-danger" style="direction:rtl" asp-validation-summary="All"></div>

simply use asp-validation-summary Tag Helper

鹿童谣 2024-08-10 12:25:01

这也有效:

var query = from state in ModelState.Values
    from error in state.Errors
    select error.ErrorMessage;
var errors = query.ToArray(); // ToList() and so on...

And this works too:

var query = from state in ModelState.Values
    from error in state.Errors
    select error.ErrorMessage;
var errors = query.ToArray(); // ToList() and so on...
寄离 2024-08-10 12:25:01

对于将错误消息数组传递给 View 很有用,也许可以通过 Json:

messageArray = this.ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors, (modelState, error) => error.ErrorMessage).ToArray();

Useful for passing array of error messages to View, perhaps via Json:

messageArray = this.ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors, (modelState, error) => error.ErrorMessage).ToArray();
淤浪 2024-08-10 12:25:01

这是对@Dunc 答案的扩展。请参阅 xml 文档注释

// ReSharper disable CheckNamespace
using System.Linq;
using System.Web.Mvc;


public static class Debugg
{
    /// <summary>
    /// This class is for debugging ModelState errors either in the quick watch 
    /// window or the immediate window.
    /// When the model state contains dozens and dozens of properties, 
    /// it is impossible to inspect why a model state is invalid.
    /// This method will pull up the errors
    /// </summary>
    /// <param name="modelState">modelState</param>
    /// <returns></returns>
    public static ModelError[]  It(ModelStateDictionary modelState)
    {
        var errors = modelState.Values.SelectMany(x => x.Errors).ToArray();
        return errors;            
    }
}

This is expanding upon the answer from @Dunc . See xml doc comments

// ReSharper disable CheckNamespace
using System.Linq;
using System.Web.Mvc;


public static class Debugg
{
    /// <summary>
    /// This class is for debugging ModelState errors either in the quick watch 
    /// window or the immediate window.
    /// When the model state contains dozens and dozens of properties, 
    /// it is impossible to inspect why a model state is invalid.
    /// This method will pull up the errors
    /// </summary>
    /// <param name="modelState">modelState</param>
    /// <returns></returns>
    public static ModelError[]  It(ModelStateDictionary modelState)
    {
        var errors = modelState.Values.SelectMany(x => x.Errors).ToArray();
        return errors;            
    }
}
残花月 2024-08-10 12:25:01

对于 AJAX 请求更好的解决方案:

    public IActionResult Demo(DemoInfo formData)
    {
        if (!ModelState.IsValid)
        {
            IEnumerable<object> formErrors = ModelState.Select((s) => new { 
                fieldName = s.Key, 
                fieldValue = s.Value.RawValue,
                fieldMessage = s.Value.Errors.FirstOrDefault()?.ErrorMessage
            });
            return Json(new { formValid = 0, formErrors });
        }
        return Json(new { formValid = 1 });
    }

响应格式将是:

{"formValid":0,
 "formErrors":[{
     "fieldName":"name of field from object",
     "fieldValue":"value from browser",
     "fieldMessage":null /*Error message from model annotations if field is valid the value will be null */
 }]
}

有关 Func<> 的更多详细信息检查此页面: Func< TSource,Int32,TResult>)

For AJAX Request better solution:

    public IActionResult Demo(DemoInfo formData)
    {
        if (!ModelState.IsValid)
        {
            IEnumerable<object> formErrors = ModelState.Select((s) => new { 
                fieldName = s.Key, 
                fieldValue = s.Value.RawValue,
                fieldMessage = s.Value.Errors.FirstOrDefault()?.ErrorMessage
            });
            return Json(new { formValid = 0, formErrors });
        }
        return Json(new { formValid = 1 });
    }

Response format will be:

{"formValid":0,
 "formErrors":[{
     "fieldName":"name of field from object",
     "fieldValue":"value from browser",
     "fieldMessage":null /*Error message from model annotations if field is valid the value will be null */
 }]
}

For more details about Func<> check this page : Func<TSource,Int32,TResult>)

故人的歌 2024-08-10 12:25:01

此外,ModelState.Values.ErrorMessage 可能为空,但 ModelState.Values.Exception.Message 可能指示错误。

In addition, ModelState.Values.ErrorMessage may be empty, but ModelState.Values.Exception.Message may indicate an error.

朱染 2024-08-10 12:25:01

获取带有字段名称和错误消息的错误

var errors = new List<ErrorDto>();
foreach (KeyValuePair<string, ModelStateEntry> kvp in context.ModelState)
{
    if (kvp.Value.Errors.Count > 0)
    {
        errors.Add(new ErrorDto()
        {
            FieldName = kvp.Key,
            ErrorMessage = string.Join(",", kvp.Value.Errors.Select(v => v.ErrorMessage))
        });
    }
}

错误模型

    public class ErrorDto
    {
        public string FieldName { get; set; }
        public string ErrorMessage { get; set; }
    }

get error with Field Name and Error Message

var errors = new List<ErrorDto>();
foreach (KeyValuePair<string, ModelStateEntry> kvp in context.ModelState)
{
    if (kvp.Value.Errors.Count > 0)
    {
        errors.Add(new ErrorDto()
        {
            FieldName = kvp.Key,
            ErrorMessage = string.Join(",", kvp.Value.Errors.Select(v => v.ErrorMessage))
        });
    }
}

Error Model

    public class ErrorDto
    {
        public string FieldName { get; set; }
        public string ErrorMessage { get; set; }
    }

小草泠泠 2024-08-10 12:25:01
var x = new Dictionary<string,string>();
for (var b = 0; b < ViewData.ModelState.Values.Count(); b++)
{
    if (ViewData.ModelState.Values.ElementAt(b).Errors.Count() > 0)
        x.Add(ViewData.ModelState.Keys.ElementAt(b), String.Join(",", ViewData
            .ModelState.Values.ElementAt(b).Errors.Select(c => c.ErrorMessage)));
}
var x = new Dictionary<string,string>();
for (var b = 0; b < ViewData.ModelState.Values.Count(); b++)
{
    if (ViewData.ModelState.Values.ElementAt(b).Errors.Count() > 0)
        x.Add(ViewData.ModelState.Keys.ElementAt(b), String.Join(",", ViewData
            .ModelState.Values.ElementAt(b).Errors.Select(c => c.ErrorMessage)));
}
枫林﹌晚霞¤ 2024-08-10 12:25:01

使用字段名称..

 if (!this.ModelState.IsValid)
 {
     foreach (var modelState in this.ModelState)
     { 
         foreach (var error in modelState.Value.Errors)
         {
             rModel.AddError(error.ErrorMessage, ErrorType.Error, modelState.Key);
         }
     }

     rModel.Message = "Invalid Data";
     return false;
 }

With fieldName ..

 if (!this.ModelState.IsValid)
 {
     foreach (var modelState in this.ModelState)
     { 
         foreach (var error in modelState.Value.Errors)
         {
             rModel.AddError(error.ErrorMessage, ErrorType.Error, modelState.Key);
         }
     }

     rModel.Message = "Invalid Data";
     return false;
 }
醉梦枕江山 2024-08-10 12:25:01

在您的实现中,您缺少静态类,这应该是。

if (!ModelState.IsValid)
{
    var errors =  ModelStateErrorHandler.GetModelErrors(this.ModelState);
    return Json(new { errors });
}

而是

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}

In your implementation you are missing static Class, this should be.

if (!ModelState.IsValid)
{
    var errors =  ModelStateErrorHandler.GetModelErrors(this.ModelState);
    return Json(new { errors });
}

rather

if (!ModelState.IsValid)
{
    var errors = ModelState.GetModelErrors();
    return Json(new { errors });
}
救赎№ 2024-08-10 12:25:01

var result = string.Join(',',ModelState.Values.SelectMany(v => v.Errors).Select(a=>a.ErrorMessage));

var result = string.Join(',',ModelState.Values.SelectMany(v => v.Errors).Select(a=>a.ErrorMessage));

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文