Entity validation error

Программист Евгений Михайлов, Блог о программировании, шаблоны проектирования, .Net programming blog, c# developer, разработка приложений, .Net tips and tricks, программирование на .Net, язык программирования C#, что почитать про Sharepoint, Sharepoint для новичка, советы по C#, learning .Net, Sharepoint tricks, MSSQL and T-SQL programming, скрипты T-SQL, полезные SQL скрипты, примеры кода C#, C# code examples

При использовании Entity Framework вы можете столкнуться с ошибкой, гласящей «Validation failed for one or more entities. See ‘EntityValidationErrors’ property for more details.» Причина появления этой ошибки в большинстве случаев — банальна, либо вы забыли какие ограничения существуют на полях в вашей базе данных, либо, если БД в вашей компании занимается отдельный человек, то он вам забыл о чем-то сообщить. ;)

EntityValidationErrors — это коллекция объектов DbEntityValidationResult, каждый из которых содержит информацию об ошибках одной EF-сущности в виде объектов DbValidationError.
На самом деле, ничего страшного в этой ошибке нет, и можно легко узнать в чем конкретно у нас ошибка в коде. Все, что для этого необходимо — это обернуться вызов метода SaveChanges() вот в такой блок try-catch:

 
                try
                {

                    DB.DB.SaveChanges();

                }
                catch (DbEntityValidationException ex)
                {
                    foreach (DbEntityValidationResult validationError in ex.EntityValidationErrors)
                    {
                        Response.Write("Object: "+validationError.Entry.Entity.ToString());
                        Response.Write("
");
                        foreach (DbValidationError err in validationError.ValidationErrors)
                        {
                            Response.Write(err.ErrorMessage + "
");
                        }
                    }
                }

Теперь повторите все те действия в результате которых появилась эта ошибка и вы увидите описание того, что не так с вашими объектами EF простым и понятным языком (в зависимости от локализации вашей ОС, конечно.

I get this message when I try to edit a property in MVC 4 database first project. I’m using the MVC default edit page.

«Validation failed for one or more entities. See «EntityValidationErrors» property for more details.»

Where do I check for validation?

hutchonoid's user avatar

hutchonoid

32.8k14 gold badges98 silver badges104 bronze badges

asked Jun 10, 2013 at 9:42

user2470369's user avatar

2

Go to your edit function, put a try — catch block and catch the exception — ‘DbEntityValidationException

if you want to see the errors, iterate though the validation errors.

here is a simple code example.

catch (DbEntityValidationException ex)
{
    foreach (var errors in ex.EntityValidationErrors)
    {
        foreach (var validationError in errors.ValidationErrors)
        {
             // get the error message 
            string errorMessage = validationError.ErrorMessage;
        }
    }
}

answered Jun 10, 2013 at 9:51

wizzardz's user avatar

wizzardzwizzardz

5,5445 gold badges44 silver badges66 bronze badges

If you set a break point in your controller you can check which values have errors against them by looking in the ModelState.
The ModelState.Values collection contains the error and the key is the field.

answered Jun 10, 2013 at 9:55

hutchonoid's user avatar

hutchonoidhutchonoid

32.8k14 gold badges98 silver badges104 bronze badges

  • Remove From My Forums
  • Question

  • Where can I check these errors ?

    Tx

    • Moved by

      Tuesday, July 22, 2014 7:45 AM

Answers

  • Hello,

    >>Where can I check these errors ?

    EntityValidationErrors is a collection which represents the entities which couldn’t be validated

    successfully, and the inner collection ValidationErrors per entity is a list of errors on property level.

    These validation messages are usually helpful enough to find the source of the problem. You can use try catch block and DbEntityValidationException to see the detail information:

    try
    
    {
    
        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;
    
    }
    

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.

    Click
    HERE to participate the survey.

    • Marked as answer by
      Fred Bao
      Wednesday, July 30, 2014 5:51 AM

Here we learn how to handle error in Entity Framework, details exception handling techniques example in C#.

Error handling is very important aspect in application development life cycle, there are many different ways error handling is implemented, while developing any application.

In this tutorial you will learn how to implement error handling in entity framework, so we can catch the right error at data access layer and make the required changes to fix the error.

One simple step to implement error handling could be using try catch block like example below.

try
    {
        using (var context = new Entities())
        {
            var query = from c in context.vwProduct
                        join o in context.tbOfferProduct on c.ProductId equals o.ProductId
                        where (o.OfferId == offerId)
                        select c;
            products = query.ToList<vwProduct>();
        }
    }
catch (Exception ex)
{
    ErrorDTO.TrackError(ex);
}

But above example may not be sufficient to know what the error is!

It will throw very common message or error in inner exception property, which may not reveal the actual error.

So, we will implement DbEntityValidationException, which will catch some entity specify error details.

catch (DbEntityValidationException e)
{
    ErrorDTO.TrackError(e.InnerException);
}

Above same example can be written differently like example below, this will help us to know exactly which field is causing error, and what type of error is that.

entity framework exception handling example

In following example, I am looping through the entity collection can catching exception details in a string builder object.

catch (DbEntityValidationException e)
{
    StringBuilder strErr = new StringBuilder();
    foreach (var eve in e.EntityValidationErrors)
    {
       
        strErr.Append($"Entity of type {eve.Entry.Entity.GetType().Name}" +
        $"in the state {eve.Entry.State} "+
        $"has the following validation errors:");


        foreach (var ve in eve.ValidationErrors)
        {
            strErr.Append($"Property: {ve.PropertyName}," +
                $" Error: {ve.ErrorMessage}");
        }


        foreach (var ve in eve.ValidationErrors)
        {
            strErr.Append($"Property: {ve.PropertyName}, " +
                $"Value: {eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName)}," +
                $" Error: {ve.ErrorMessage}");
        }


    }
        ErrorDTO.TrackError("AddProduct", strErr.ToString());
}

Apart from above DbEntityValidationException, there are few other type of exception, which are also helpful in some scenario, like EntityCommandExecutionException, DbUpdateException etc.

Here is the complete exception handling implementation example,
Notice, how to catch Entity Validation Errors in following code

    
using System.Data.Entity.Validation;
using System.Data.Entity.Infrastructure;
using System.Data.Entity;
using System.Data.Entity.Core;


public List<vwProduct> GetProductsByOffer(long offerId)
        {
            List<vwProduct> products = null;
            try
            {
                using (var context = new Entities())
                {
                    var query = from c in context.vwProduct
                                join o in context.tbOfferProduct on c.ProductId equals o.ProductId
                                where (o.OfferId == offerId)
                                select c;
                    products = query.ToList<vwProduct>();
                }
            }
    catch (DbEntityValidationException e)
    {
        StringBuilder strErr = new StringBuilder();
        foreach (var eve in e.EntityValidationErrors)
        {
        strErr.Append($"Entity of type {eve.Entry.Entity.GetType().Name}" +
        $"in the state {eve.Entry.State} "+
        $"has the following validation errors:");
        foreach (var ve in eve.ValidationErrors)
        {
            strErr.Append($"Property: {ve.PropertyName}," +
                $" Error: {ve.ErrorMessage}");
        }
        foreach (var ve in eve.ValidationErrors)
        {
            strErr.Append($"Property: {ve.PropertyName}, " +
                $"Value: {eve.Entry.CurrentValues.GetValue<object>(ve.PropertyName)}," +
                $" Error: {ve.ErrorMessage}");
        }
        }
        ErrorDTO.TrackError("AddProduct", strErr.ToString());
    }
    catch (DbUpdateException ex)
    {
        ErrorDTO.TrackError(ex.Source, ex.InnerException);
    }
    catch (EntityCommandExecutionException cex)
    {
        ErrorDTO.TrackError(cex.InnerException);
    }
    catch (Exception ex)
    {
        ErrorDTO.TrackError(ex);
    }
    return products;
        }
			

ex {«An error occurred while executing the command definition. See the inner exception for details.»}
System.Exception {System.Data.Entity.Core.EntityCommandExecutionException}

While dealing with complex entity, we should think of implementing all possible exception type, so the code can catch the exact error message and provide the log details to developers, it will be easy to fix the error quickly.

Easy way to improve DbEntityValidationException of Entity Framework

DbEntityValidationException is the exception thrown by Entity Framework when entity validation fails. While this exception is extremely valuable, the exception message omits the most important bit of information: The actual validation errors. In this blog, I present a quick and easy way to unwrap and rethrow these exceptions with a more meaningful message.

Developers who have used Entity Framework are probably familiar with the following message:

System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

This message is quite clear in its intent: Something isn’t valid and if you want to find out what that is then you should attach a debugger and inspect the exception. While this is certainly a valid approach, attaching debuggers isn’t always practical (e.g. production environments). Moreover, being the lazy developer I am, I don’t want to attach a debugger to find out what field caused the error: I want the exception message to tell me in the first place!

DbEntityValidationException is thrown by the SaveChanges method which resides on the DbContext class. Fortunately, you can override the default behavior of SaveChanges. Assuming you use a database-first approach, your Visual Studio solution should contain a bunch of files like these:

  • Northwind.cs
  • Northwind.Context.cs
  • Northwind.Context.tt
  • Northwind.Designer.cs
  • Northwind.edmx
  • Northwind.edmx.diagram
  • Northwind.tt

Northwind.Context.cs is the file of interest here. This file is automatically generated by Northwind.Context.tt. It describes the class you use in code to perform operations on the database. This class inherits from DbContext, which in turn contains SaveChanges, the method responsible for throwing the DbEntityValidationException. This method is virtual and can thus be overridden. However, changing Northwind.Context.cs is not recommended since the tt-file will overwrite this file on any change to the EDMX. Luckily, the class itself is partial, which means you can add your own class to the solution.

  1. First, create a new partial class in the same location as where your EDMX resides. In my example, I called the file NorthwindEntities.cs, which is also the name of the class.
  2. Second, use the following piece of C# code to override the SaveChanges implementation.
public partial class NorthwindEntities
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            // Retrieve the error messages as a list of strings.
            var errorMessages = ex.EntityValidationErrors
                    .SelectMany(x => x.ValidationErrors)
                    .Select(x => x.ErrorMessage);

            // Join the list to a single string.
            var fullErrorMessage = string.Join(&quot;; &quot;, errorMessages);

            // Combine the original exception message with the new one.
            var exceptionMessage = string.Concat(ex.Message, &quot; The validation errors are: &quot;, fullErrorMessage);

            // Throw a new DbEntityValidationException with the improved exception message.
            throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
        }
    }
}

That’s it! The rest of your code will automatically use the overridden SaveChanges so you don’t have to change anything else. From now on, your exceptions will look like this:

System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. The validation errors are: The field PhoneNumber must be a string or array type with a maximum length of '12'; The LastName field is required.

The DbEntityValidationException also contains the entities that caused the validation errors. So if you require even more information, you can change the above code to output information about these entities.

I hope this blog saves you time debugging, so you can spend more time writing awesome code instead! 🙂

This article is also featured on StackOverflow and My Personal Blog!

Share this

How to get error messages from EntityValidationErrors?


Sometimes, we see following error message while working with Entity Framework in ASP.NET MVC.

Validation failed for one or more entities. See ‘EntityValidationErrors’ property for more details.

To get error messages from EntityValidationErrors, we can loop through them that is nothing but collection of DbEntityValidationResult and then each DbEntityValidationResult object has ValidationErrors property that actually gives the error message.

public ActionResult ReceiveParameters(PersonalDetails pd)
        {
            try
            {
                db.PersonalDetails.Add(pd);
                db.SaveChanges();
            }
            catch (DbEntityValidationException ee)
            {
                foreach (var error in ee.EntityValidationErrors)
                {
                    foreach(var thisError in error.ValidationErrors)
                    {
                        var errorMessage = thisError.ErrorMessage;
                    }                    
                }
            }
            return View();
        }

Notice in the above code snippet, when an error occurs in the try block, it throws DbEntityValidationException error because all the code that is written in the try block is Entity Framework code. We are getting the EntityValidationErrors property of the error object (ee) and interating through each DbEntityValidationResult(error in first foreach loop) that in iterm gives collection of DbValidationError collection. Each DbValidationError object (thisError) has ErrorMessage property that shows the actual error occured.

 Views: 16425 | Post Order: 86



Related Posts

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Epc vag ошибка
  • Empyrion galactic survival как изменить имя игрока
  • Entext dll ошибка
  • Epc mercedes ошибка w210
  • Enterprise pki error

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии