How to get all Errors from ASP.Net MVC modelState?
我想在不知道键值的情况下从modelState中获取所有错误消息。 遍历以获取ModelState包含的所有错误消息。
我怎样才能做到这一点?
1 2 3 4 5 | foreach (ModelState modelState in ViewData.ModelState.Values) { foreach (ModelError error in modelState.Errors) { DoSomethingWith(error); } } |
另请参见如何在ASP.NET MVC中收集模型状态错误?
使用LINQ:
1 | IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors); |
如果您想将所有错误消息连接到一个字符串中,则以LINQ版本为基础:
1 2 3 | string messages = string.Join(";", ModelState.Values .SelectMany(x => x.Errors) .Select(x => x.ErrorMessage)); |
我可以使用LINQ做到这一点,
1 2 3 4 5 6 7 8 9 10 | 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读取所有错误
在调试期间,我发现在每个页面的底部放置一个表格以显示所有ModelState错误很有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <table class="model-state"> @foreach (var item in ViewContext.ViewData.ModelState) { if (item.Value.Errors.Any()) { <tr> <td>@item.Key</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> |
正如我发现遵循到目前为止给出的答案中的建议那样,您可以在不设置错误消息的情况下发生异常,因此要捕获所有真正需要同时获取ErrorMessage和Exception的问题。
1 2 | String messages = String.Join(Environment.NewLine, ModelState.Values.SelectMany(v => v.Errors) .Select( v => v.ErrorMessage +"" + v.Exception)); |
或作为扩展方法
1 2 3 4 5 6 | public static IEnumerable<String> GetErrors(this ModelStateDictionary modelState) { return modelState.Values.SelectMany(v => v.Errors) .Select( v => v.ErrorMessage +"" + v.Exception).ToList(); } |
如果有人想返回Model属性的名称,以便在强类型视图中绑定错误消息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); } } |
这样,您实际上可以将错误与引发错误的字段联系在一起。
仅输出错误消息本身对我来说还不够,但这确实可以解决问题。
1 2 3 4 5 6 7 8 9 10 | 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)); |
以防万一有人需要它,我在我的项目中使用了以下静态类
用法示例:
1 2 3 4 5 | if (!ModelState.IsValid) { var errors = ModelState.GetModelErrors(); return Json(new { errors }); } |
Usings:
1 2 3 4 5 | using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using WebGrease.Css.Extensions; |
类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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(); } } |
这扩展了@Dunc的答案。查看xml文档注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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; } } |
这也有效:
1 2 3 4 | var query = from state in ModelState.Values from error in state.Errors select error.ErrorMessage; var errors = query.ToArray(); // ToList() and so on... |
有助于通过Json将错误消息数组传递给View:
1 | messageArray = this.ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors, (modelState, error) => error.ErrorMessage).ToArray(); |
此外,
我不知道这是我的问题,有时我在ModelState的ErrorMessage部分中收到消息,有时在ModelState错误的异常消息中得到消息。
因此,我创建了一个可以同时处理这两种情况的方法。希望这对这里的每个人都有帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public static string GetErrorMessageFromModelState(ModelStateDictionary modelState) { string errorMessage = string.Empty; try { string[] errorMessageList = (from m in modelState where m.Value.Errors.Count > 0 select string.Join(",", m.Value.Errors.Select(x => !string.IsNullOrEmpty(x.ErrorMessage) ? x.ErrorMessage : !string.IsNullOrEmpty(x.Exception.Message) ? x.Exception.Message.Split('\'').Length > 0 ? x.Exception.Message.Split('\'')[1].ToString() : m.Key.Split('.').Length > 1 ? m.Key.Split('.')[1] : m.Key.Split('.')[0] : m.Key.Split('.')[0]))).ToArray(); errorMessage = string.Format("Error in Field(s):" + string.Join(",", errorMessageList) +" {0} required.", (errorMessageList.Count() > 1 ?"are" :"is")); } catch (Exception ex) { errorMessage = ex.Message; if (ex.InnerException != null) errorMessage += Environment.NewLine + ex.InnerException; } return errorMessage; } |
在您的实现中,您应该缺少静态类。
1 2 3 4 5 | if (!ModelState.IsValid) { var errors = ModelStateErrorHandler.GetModelErrors(this.ModelState); return Json(new { errors }); } |
宁
1 2 3 4 5 | if (!ModelState.IsValid) { var errors = ModelState.GetModelErrors(); return Json(new { errors }); } |