Validation Failed For One or More Entities. See 'Entityvalidationerrors' Property For More Details

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

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.

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:

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 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.

Edit

A few slight improvements:

The value of the offending property can be included in the inner loop like so:

        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);
}

While debugging Debug.Write might be preferable over Console.WriteLine as it works in all kind of applications, not only console applications (thanks to @Bart for his note in the comments below).

For web applications that are in production and that use Elmah for exception logging it turned out to be very useful for me to create a custom exception and overwrite SaveChanges in order to throw this new exception.

The custom exception type looks like this:

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

And SaveChanges can be overwritten the following way:

public class MyContext : DbContext
{
// ...

public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException e)
{
var newException = new FormattedDbEntityValidationException(e);
throw newException;
}
}
}

A few remarks:

  • 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.

  • Overwriting the Message property in the custom exception instead of overwriting ToString() 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 ToString(), but both display the Message property.

  • Wrapping the original DbEntityValidationException as inner exception ensures that the original stack trace will still be available and is displayed in Elmah and the YSOD.

  • By setting a breakpoint on the line throw newException; you can simply inspect the newException.Message 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).

MVC5 Validation failed for one or more entities. See 'EntityValidationErrors' property for more details

a simple solution would be to add this line to the watch window:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

but my guess would be that the error comes from the ApplicationUser's UserName property, you need to give it a valu while adding a new user :)

i hope it helped.

Create Submit Error: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details

All fields except ID is nullable in SQL.

That's not what you told Entity Framework, which is what's throwing the error. (And, as the error indicates, you should really check the EntityValidationErrors property on the exception, or an inner exception, for specific information about the error.) You told Entity Framework that these fields are required:

[Required(ErrorMessage = "Requested By Required.")]
public string Request { get; set; }

[Required(ErrorMessage = "Request Required.")]
public string Resolution { get; set; }

(It looks like you may have mixed up some of the property attributes, judging by the messages on them.)

I know that the issue is coming from the fields resolution and technician - if I put them on the create form (which they are not on it now as I do not want them filled out) the submit works fine

Sounds like that's the problem then. Resolution is marked as required, and you're not including it. Either include it or don't make it required.

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. ASP.NET MVC

Look at your model definition

// This means this value is required 
// and should not be greater than 255 characters
[Required]
[StringLength(255)]
public string PetName { get; set; }

// This means this value is required
// and should not be greater than 6 characters
[Required]
[StringLength(6)]
public string PetGender { get; set; }

So either you are not sending a value from your client app or it is larger than the restrictions you stated.
Change your action method to this to validate your model in your backend (you should never trust the client input)

[HttpPost]
public ActionResult Save(PetRescued petRescued)
{
if (ModelState.IsValid) // Check for errors
{
if (petRescued.Id == 0)
_context.PetRescueds.Add(petRescued);
else
{
var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
petRescuedInDb.PetName = petRescued.PetName;
petRescuedInDb.PetAge = petRescued.PetAge;
petRescuedInDb.PetGender = petRescued.PetGender;
petRescuedInDb.PetWeightInKg = petRescued.PetWeightInKg;
petRescuedInDb.PetSpeciesId = petRescued.PetSpeciesId; //strange
petRescuedInDb.DateWhenRescued = petRescued.DateWhenRescued;
}

_context.SaveChanges();
return RedirectToAction("Index", "PetRescued");
}
else
return View(petRescued); // Return the same view with the original data
// or with the correct model of your view, at least
}

UPDATE

Correct your view model to reflect your correct data. That means, make sure you are sending the correct model to the backend. ASP.Net MVC has something called Model Binding, which is the mechanism used to convert the data received from the client into your C# model. By default, it works by detecting the name of the values passed from the client and finding an exact mapping with the properties of the model. That means that in your view you are declaring this

    @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })

So, if you inspect the data sent by the browser you will see that the form data includes something like

PetRescueds.PetAge: whatever_the_client_typed

That will not be mapped to your model, because your model doesn't have a property named PetRescueds with a subproperty named PetName, your action model is directly a PetRescued model. So either change your view by specifying directly the name attr like this

    @Html.TextBox("PetName", Model.PetRescueds.PetName, new { @class = "form-control" })

Or change your action model to reflect your view model definition. Either way, your view model should be consistent through your action and view. Otherwise, you will end up receiving null values in your action model in spite of filling them correctly on your view, or showing empty values in your views regardless of what you actually created on your controller action.

So, basically, check your model definitions. Make sure you are using a correct model definition to display in your views. Make sure your view is correctly defined as to what you are expecting to receive in your backend controller.

Then, change your view to include validation errors retrieved from the server

@using (Html.BeginForm("Save", "PetRescued"))
{
<!-- This will show your errors-->
@Html.ValidationSummary()
<div class="form-group">
@Html.LabelFor(m => m.PetRescueds.PetName)
<!-- Or you can show errors for each model property -->
<!-- like this -->
@Html.ValidationMessageFor(m => m.PetRescueds.PetName);
@Html.TextBox("PetName", Model.PetRescueds.PetName, new { @class = "form-control" })
</div>

//strange
<div class="form-group">
@Html.LabelFor(m => m.PetSpecies)
@Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})
</div>

<div class="form-group">
@Html.LabelFor(m => m.PetRescueds.PetAge)
@Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
</div>

<div class="form-group">
@Html.LabelFor(m => m.PetRescueds.PetGender)
@Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
</div>

<div class="form-group">
@Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
@Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
</div>

<div class="form-group">
@Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
@Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" })
</div>

@Html.HiddenFor(m => m.PetRescueds.Id)
<button type="submit" class="btn btn-primary">Save</button>
}

You can read more about data validation at Microsofts's

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. in mvc

This is usually an error with your entity framework while trying to perform a database operation. Here is a modified example from TechFunda showing how to see what your entity validation errors are so that you can fix them. If you look at the errorMessage varaible while debugging it should tell you what your actual error is.

public ActionResult ReceiveParameters(PersonalDetails pd)
{
try
{
//Entity Framework Code You are executing
}
catch (DbEntityValidationException ee)
{
foreach (var error in ee.EntityValidationErrors)
{
foreach(var thisError in error.ValidationErrors)
{
var errorMessage = thisError.ErrorMessage;
}
}
}
return View();
}

Source: TechFunda Article



Related Topics



Leave a reply



Submit