При использовании 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
32.8k14 gold badges98 silver badges104 bronze badges
asked Jun 10, 2013 at 9:42
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
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
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
-
Moved by
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
-
Marked as answer by
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.
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.
- 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.
- 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("; ", errorMessages); // Combine the original exception message with the new one. var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", 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