Я хочу получить все сообщения об ошибках из modelState, не зная значений ключей. Прокрутка, чтобы захватить все сообщения об ошибках, содержащиеся в ModelState.Как получить все ошибки из ASP.Net MVC modelState?
Как это сделать?
Я хочу получить все сообщения об ошибках из modelState, не зная значений ключей. Прокрутка, чтобы захватить все сообщения об ошибках, содержащиеся в ModelState.Как получить все ошибки из ASP.Net MVC modelState?
Как это сделать?
foreach (ModelState modelState in ViewData.ModelState.Values) {
foreach (ModelError error in modelState.Errors) {
DoSomethingWith(error);
}
}
См. Также How do I get the collection of Model State Errors in ASP.NET MVC?.
Очень полезно. Обратите внимание, что в некоторых сценариях, таких как сбои привязки и неудачные запросы, будут записи ModelState с пустой строкой для 'Value.ErrorMessage' и вместо этого значение Value.Exception.Message' – AaronLS
Использование LINQ:
IEnumerable<ModelError> allErrors = ModelState.Values.SelectMany(v => v.Errors);
Изменено для возврата IEnumerable
Это замечательно, но, к сожалению, Watch/Immediate windows не поддерживают lambda's :( – AaronLS
Не работает для меня. Значения не содержат определения для Select many. Должен ли я включать что-либо, любую библиотеку, LINQ или что-то еще? – Estevez
Опираясь на verison LINQ, если вы хотите присоединиться все сообщения об ошибках в одну строку:
string messages = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
Другой вариант - сделать следующее: ModelState.Values.SelectMany (x => x.Errors) .Выберите (x => x.ErrorMessage) .JoinString (";"); –
@Tod, IEnumerable.JoinString() ваш собственный метод расширения? См. Http://stackoverflow.com/q/4382034/188926 – Dunc
Эй, Dunc - да, я подозреваю, что добавил этот метод расширения к моей базе кода и забыл об этом, а затем подумал, что это был метод структуры LOL :( –
И это тоже работает:
var query = from state in ModelState.Values
from error in state.Errors
select error.ErrorMessage;
var errors = query.ToArray(); // ToList() and so on...
@Yasser Вы видели ответ Тото? –
@ TheMuffinMan да есть. Что насчет этого ? – Yasser
@ Yasser Это лучший ответ. Ничего плохого в этом нет, но не стоит использовать его, когда доступно 'SelectMany'. –
Кроме того, ModelState.Values.ErrorMessage
может быть пустым, но ModelState.Values.Exception.Message
может указывать ели ошибку.
я был в состоянии сделать это, используя немного 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;
}
выше метод возвращает список ошибок проверки.
Дополнительная литература:
+1 для того, чтобы быть более полезным во время отладки, поскольку это метод расширения –
Во время отладки я считаю полезным, чтобы поместить таблицу в нижней части каждого из моих страниц, чтобы показать все ошибки 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>
, если есть какие-либо случаи края здесь, где это не удается, просто отредактируйте ответ, чтобы исправить его. –
Как я обнаружил последовав совет в ответах до сих пор, вы можете получить исключения, происходящие без сообщений об ошибках быть установлены, так, чтобы охватить все проблемы, которые действительно нужны, чтобы получить как ErrorMessage и исключение.
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();
}
Почему вы хотите строку со всеми ошибками в ней? не имеет смысла, когда вы хотите что-то сделать с ним в представлении, массив списка лучше, чем imho. –
Отладка. Моя первая проблема заключалась в том, чтобы выяснить, что не так с моим приложением. Я не пытался сказать, что пользователь просто узнает, что происходит не так. Кроме того, тривиально преобразовать этот пример из создания перечисления строк в перечисление чего-то другого, например. сообщение об ошибке и исключение, поэтому действительно полезно знать, что вам нужны оба бита информации. –
Кстати, вы поняли, что второй метод расширения возвращает IEnumerable
полезное для передачи массива сообщений об ошибках для просмотра, возможно, через Json:
messageArray = this.ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors, (modelState, error) => error.ErrorMessage).ToArray();
Это расширяет на ответ от @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;
}
}
Для только в случае, если кто-то это нужно я сделал и использовать следующий статический класс в моих проектах
Пример использования:
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;
Класс:
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();
}
}
Спасибо CodeArtist !! Я сделал небольшое изменение в коде ниже его реализации. –
В вашей реализации вам не хватает статического класса, это должно быть.
if (!ModelState.IsValid)
{
var errors = ModelStateErrorHandler.GetModelErrors(this.ModelState);
return Json(new { errors });
}
довольно
if (!ModelState.IsValid)
{
var errors = ModelState.GetModelErrors();
return Json(new { errors });
}
В случае, если кто хочет вернуть имя свойства модели для связывания сообщения об ошибке в сильно типизированной.
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);
}
}
Таким образом, вы действительно можете связать ошибку с полем, в котором была ошибка.
Вывод только сообщений об ошибках сам по себе был недостаточным для меня, но это сделало трюк.
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));
В качестве предупреждения пары ключевых значений в ModelState могут включать значения NULL, поэтому исходный код здесь включает в себя некоторые симпатичные операции C# 6 с оператором null-coalesce (?.), Следовательно, currying to the ?? в конце выражения. Исходным выражением, которое должно защищать от нулевых ошибок, было: state.Value.?AttemptedValue ?? "[НОЛЬ]". Насколько мне известно, код в его текущем состоянии, без скрытой обработки случаев, когда state.Value == null, находится под угрозой. –
Если вы просто показываете ошибки, то '@ Html.ValidationSummary()' - это быстрый способ отобразить их все в бритве. – levininja
'foreach (ошибка var в ViewData.ModelState.Values.SelectMany (modelState => modelState.Errors)) {DoSomething (ошибка); } ' –