Если честно, я не знаю, как проверить содержание ошибок проверки. Visual Studio показывает, что это массив с 8 объектами, поэтому 8 ошибок валидации.
На самом деле вы должны увидеть ошибки, если во время отладки вы углубитесь в этот массив в Visual studio. Но вы также можете перехватить исключение и записать ошибки в какое-либо хранилище журналов или консоль:
try
{
// Your code...
// Could also be before try if you know the exception occurs in SaveChanges
context.SaveChanges();
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
EntityValidationErrors
- это коллекция, представляющая сущности, которые не могут быть успешно проверены, а внутренняя коллекция ValidationErrors
для каждой сущности - это список ошибок на уровне свойства.
Эти проверочные сообщения обычно достаточно полезны, чтобы найти источник проблемы.
Редактировать
Несколько небольших улучшений:
Значение свойства-нарушителя может быть включено во внутренний цикл следующим образом:
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
ve.PropertyName,
eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
ve.ErrorMessage);
}
Хотя отладка Debug.Write
может быть предпочтительнее, чем Console.WriteLine
, поскольку она работает во всех видах приложений, а не только в консольных приложениях (спасибо @Bart за его примечание в комментариях ниже).
Для веб-приложений, работающих и использующих Elmah для регистрации исключений, для меня оказалось очень полезным создать пользовательское исключение и перезаписать SaveChanges
, чтобы вызвать это новое исключение.
Тип пользовательского исключения выглядит следующим образом:
public class FormattedDbEntityValidationException : Exception
{
public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
base(null, innerException)
{
}
public override string Message
{
get
{
var innerException = InnerException as DbEntityValidationException;
if (innerException != null)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine();
foreach (var eve in innerException.EntityValidationErrors)
{
sb.AppendLine(string.Format("- Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().FullName, eve.Entry.State));
foreach (var ve in eve.ValidationErrors)
{
sb.AppendLine(string.Format("-- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"",
ve.PropertyName,
eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName),
ve.ErrorMessage));
}
}
sb.AppendLine();
return sb.ToString();
}
return base.Message;
}
}
}
И SaveChanges
могут быть перезаписаны следующим образом:
public class MyContext : DbContext
{
// ...
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException e)
{
var newException = new FormattedDbEntityValidationException(e);
throw newException;
}
}
}
Несколько замечаний:
Желтый экран ошибки, который Elmah показывает в веб-интерфейсе или в отправленных электронных письмах (если вы это настроили), теперь отображает сведения о проверке непосредственно в верхней части сообщения.
Перезапись свойства Message
в пользовательском исключении вместо перезаписи ToString()
имеет то преимущество, что стандартный ASP.NET «Желтый экран смерти (YSOD)» также отображает это сообщение. В отличие от Эльмы, YSOD, очевидно, не использует ToString()
, но оба отображают свойство Message
.
Оборачивание оригинальной DbEntityValidationException
как внутреннего исключения гарантирует, что исходная трассировка стека все еще будет доступна и будет отображаться в Elmah и YSOD.
Устанавливая точку останова на строке throw newException;
, вы можете просто просмотреть свойство newException.Message
в виде текста, а не углубляться в проверочные коллекции, что немного неудобно и, похоже, не так легко для всех (см. комментарии ниже).