Getting exact error type in from DbValidationException

55,547

Solution 1

While you are in debug mode within the catch {...} block open up the "QuickWatch" window (ctrl+alt+q) and paste in there:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

This will allow you to drill down into the ValidationErrors tree. It's the easiest way I've found to get instant insight into these errors.

For Visual 2012+ users who care only about the first error and might not have a catch block, you can even do:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage

Solution 2

You could try this in a try/catch block?

catch (DbEntityValidationException dbEx)
{
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
        }
    }
}

Solution 3

The best solution in my opinion, is to handle this kind of errors in a centralized way.

just add this method to the main DbContext class :

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
        throw new DbEntityValidationException(errorMessages);
    }
}

This will overwrite your context's SaveChanges() method and you'll get a comma separated list containing all the entity validation errors.

hope this is helpful.

Solution 4

Well, I had same problem. My model worked good in EF CTP5 but failed to build in 4.1 with the same error ""Validation failed for one or more entities" when I tried to initalize it. I figured out that I had property:

public string Comment {get; set;}

Then in seed method in overrided initializer, I had quite a bit long (about 600 letters) comment.

I think the point is: in EF 4.1 you have to set data annotations explicitly in some cases. For me, setting:

[StringLength(4000)] 
public string Comment {get; set;}

helped. It's weird since CTP5 had no problems with that.

Solution 5

I know it's an old question but here's my answer:

catch (DbEntityValidationException ex)
   {
    String.Join("\n", ex.EntityValidationErrors
          .SelectMany(x => x.ValidationErrors)
          .Select(x => x.ErrorMessage)
          .ToArray());
   }

and if you use code first, you can also globalize your error messages using multiple resource files

For instance I have these two seperate resource file, one for error and one for property name and I use them as following: enter image description here enter image description here

public class Person 
    {
        [Required(ErrorMessageResourceName = "required",ErrorMessageResourceType =typeof(ErrorMessages))]
        [MaxLength(100,ErrorMessageResourceName = "maxLength", ErrorMessageResourceType = typeof(ErrorMessages))]
        [Display(Name = "FirstName",ResourceType = typeof(Properties))]
        public string FirstName { get; set; }
         }

As you can see I have completely translated my error messages including the properties names, so I could then use them in the user later for instance:

enter image description here

Share:
55,547
Naz
Author by

Naz

I'm a developer specializing in JavaScript stack and all kinds of related technologies.

Updated on December 30, 2021

Comments

  • Naz
    Naz over 2 years

    I have the situation where I'm initializing my model in DatabaseInitializer() for EF 4.1 and get this annoying error "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." So, I go to this EntityValidationErrors and there is a field {System.Data.Entity.Validation.DbEntityValidationResult} which gives me no information at all about what field it was unable to initialize. Is there a way to get more info about this error?

    To clear things out:

    I know how to fix the string length problem. What I'm asking is how do I get the exact field name that is breaking the model.

  • Naz
    Naz about 13 years
    Well what I was asking is how do I get exact property name that is breaking the model. Though, I managed to overcome the problem you stated using [StringLength(Int32.MaxValue)] as an attribute for my property (as it was suggested by Ladislav Mrnka and I talked about it in this question stackoverflow.com/questions/5346155/…) Powodzenia! =)
  • Roberto Bonini
    Roberto Bonini about 13 years
    This got thrown when I added a new property to my model in 4.1. Was working perfectly in 4.1 before. Weird. Solved by adding annotation to all the properties in the model.
  • Ecyrb
    Ecyrb over 12 years
    If you don't have a catch block, you can replace ex with $exception and get the same result.
  • Eonasdan
    Eonasdan over 11 years
    also make sure you replace ex with w/e your catch (Exception THIS) is
  • matrix
    matrix over 10 years
    @Ecyrb, thanks. you saved hours of Googling. Also, even if the validation error count is shown as 1, there are actually two elements in the array with two errors.
  • Tim Pohlmann
    Tim Pohlmann about 8 years
    This does not work for me (VS2015) "error CS0103: The name '$exception' does not exist in the current context"
  • GONeale
    GONeale about 8 years
    @TimPohlmann You have to do it while you are currently debugging.
  • Tim Pohlmann
    Tim Pohlmann about 8 years
    @GONeale I did try it while debugging
  • jpsimard-nyx
    jpsimard-nyx about 8 years
    For those not referencing System.Linq and using immediate window: System.Linq.Enumerable.ToList(System.Linq.Enumerable.ToList(‌​((System.Data.Entity‌​.Validation.DbEntity‌​ValidationException)‌​$exception).EntityVa‌​lidationErrors)[0].V‌​alidationErrors)[0].‌​ErrorMessage
  • Mark
    Mark over 3 years
    Creating a string using this string.Join() of the error property and messages was helpful for use in an error logging system.
  • jacobkim
    jacobkim over 2 years
    It seems the answer could be a reply to the question.