Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>To be honest I don't know how to check the content of the validation errors. Visual Studio shows me that it's an array with 8 objects, so 8 validation errors.</p> </blockquote> <p>Actually you should see the errors if you drill into that array in Visual studio during debug. But you can also catch the exception and then write out the errors to some logging store or the console:</p> <pre><code>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; } </code></pre> <p><code>EntityValidationErrors</code> is a collection which represents the entities which couldn't be validated successfully, and the inner collection <code>ValidationErrors</code> per entity is a list of errors on property level.</p> <p>These validation messages are usually helpful enough to find the source of the problem. </p> <p><strong>Edit</strong></p> <p>A few slight improvements:</p> <p>The <em>value</em> of the offending property can be included in the inner loop like so:</p> <pre><code> foreach (var ve in eve.ValidationErrors) { Console.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"", ve.PropertyName, eve.Entry.CurrentValues.GetValue&lt;object&gt;(ve.PropertyName), ve.ErrorMessage); } </code></pre> <p>While debugging <code>Debug.Write</code> might be preferable over <code>Console.WriteLine</code> as it works in all kind of applications, not only console applications (thanks to @Bart for his note in the comments below).</p> <p>For web applications that are in production and that use <strong>Elmah</strong> for exception logging it turned out to be very useful for me to create a custom exception and overwrite <code>SaveChanges</code> in order to throw this new exception.</p> <p>The custom exception type looks like this:</p> <pre><code>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&lt;object&gt;(ve.PropertyName), ve.ErrorMessage)); } } sb.AppendLine(); return sb.ToString(); } return base.Message; } } } </code></pre> <p>And <code>SaveChanges</code> can be overwritten the following way:</p> <pre><code>public class MyContext : DbContext { // ... public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException e) { var newException = new FormattedDbEntityValidationException(e); throw newException; } } } </code></pre> <p>A few remarks:</p> <ul> <li><p>The yellow error screen that Elmah shows in the web interface or in the sent emails (if you have configured that) now displays the validation details directly at the top of the message.</p></li> <li><p>Overwriting the <code>Message</code> property in the custom exception instead of overwriting <code>ToString()</code> has the benefit that the standard ASP.NET "Yellow screen of death (YSOD)" displays this message as well. In contrast to Elmah the YSOD apparently doesn't use <code>ToString()</code>, but both display the <code>Message</code> property.</p></li> <li><p>Wrapping the original <code>DbEntityValidationException</code> as inner exception ensures that the original stack trace will still be available and is displayed in Elmah and the YSOD.</p></li> <li><p>By setting a breakpoint on the line <code>throw newException;</code> you can simply inspect the <code>newException.Message</code> property as a text instead of drilling into the validation collections which is a bit awkward and doesn't seem to work easily for everyone (see comments below).</p></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload