This question already has answers here:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details [duplicate]
(29 answers)
Closed 2 years ago.
My app gets the following error:
An exception of type
'System.Data.Entity.Validation.DbEntityValidationException' occurred
in EntityFramework.dll but was not handled in user code
Additional information: Validation failed for one or more entities.
See 'EntityValidationErrors' property for more details.
I get this error when trying to register a new user. Error happens on 'db.SaveChanges()'
Here is the code:
public ActionResult Registration(x.Models.User user)
{
if(ModelState.IsValid)
{
using(var db = new xDBEntities1())
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(user.password);
var sysUser = db.users.Create();
sysUser.email = user.email;
sysUser.username = user.username;
sysUser.password = encrpPass;
sysUser.premium_credits = 0;
sysUser.login_times = 0;
sysUser.last_ip = Request.ServerVariables["REMOTE_ADDR"];
sysUser.creation_ip = Request.ServerVariables["REMOTE_ADDR"];
sysUser.banned = 0;
sysUser.creation_date = DateTime.Now;
sysUser.creation_time = DateTime.Now.TimeOfDay;
db.users.Add(sysUser);
db.SaveChanges();
}
}
return RedirectToAction("Index", "Home");
}
edit:
User model class
public class User
{
[Required]
[StringLength(50)]
[Display(Name="Username: ")]
public String username { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(50,MinimumLength=6)]
[Display(Name="Password: ")]
public string password { get; set; }
[Required]
[EmailAddress]
[StringLength(50)]
public string email { get; set; }
public int phonenumber { get; set; }
public int mobilephonenumber { get; set; }
}
}
How can I handle it ?
To solve this error, we can wrap the SaveChanges() method of DatabaseContext object in try block and in the Catch loop through each errors to find out where the error is. The code goes below.
try
{
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
foreach (var entityValidationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in entityValidationErrors.ValidationErrors)
{
Response.Write("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
}
}
}
Once the error is found, you can work on that to fix it.
Hope this helps.
There is some sort of database validation happening preventing you from writing the data into it.
The solution is already stated on this page:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
As an extra note to this as you are using .net mvc you should use System.Diagnostics.Debug.WriteLine() instead of Console.Writeline() and this will write to the debug output window when you are debugging. As you cannot write to the console when running a mvc project.
You can override the SaveChanges, to handle this exception and provide better exception details.
You can create a class "next" to your context class... the full code for that class is as follow:
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
namespace MyNamespace
{
public partial class MyContext : DbContext
{
// Override base SaveChanges to expand out validation errors so client gets an actually helpful message
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);
}
}
}
}
Check this for more information: http://devillers.nl/blog/improving-dbentityvalidationexception/
Even though there is an accepted answer already, my experience could probably help someone in the future. For a quick test you can check the data which you are inputting to the database in Configuration.cs file and then in Model you can check the validation conditions. For example, in my case I would put following validation condition in a model:
[Range(1, 100),DataType(DataType.Currency)]
public decimal Price { get; set; }
And then, inside the Configuration.cs assigning the price to be:
new Photo{
Title = "Photo 2",
DateTaken = DateTime.Parse("2013-6-15"),
Genre = "Nature",
CameraModel = "Canon",
Price = 200
}
This, created EntityFrameworkExceptions and prevented database from seeding.
The password Length in the DB and the Model must be >= that the length of encrpPass.
Check the size of the database fields that you are trying to save data to. Changing a field from varchar(50) to varchar(max) did the trick for me.
If you are using Entity Framework you might have to delete and add the table that you made changes to.
Maybe this is helpful for someone :
This error occurred because I changed the field properties in EF SQL Server DB from var(100) to var(200). I updated properly in the DB, but forgot to update the ADO properties. In the .edmx file you can click on the columnname and change the properties, after that it worked for me.
Related
I am creating a customer model for my API and I've set my 'Name' and 'Email' fields as required. But when we leave those fields empty while creating a new customer, we got a built-in error from EF core , instead I want to show my own error message...how can I do that.
I've tried to add validations by code in my post method but It doesn't work...can anyone help me with that?...Thanks in advance
If you want to do simple validation: Fluent Validation
public class UserRegisterValidator : AbstractValidator<User>
{
public UserRegisterValidator()
{
RuleFor(r => r.email).NotEmpty().WithMessage("Email address cannot be empty.");
.
.
.
}
}
When adding a new user
UserRegisterValidator v = new UserRegisterValidator();
ValidationResult result = v.Validate(usr);
if (!result.IsValid) return StatusCode(StatusCodes.Status400BadRequest, result.Errors); //Returns the specified error message
if (result.IsValid)
{
//If there is no error, the necessary actions are here
}
If you want to use server side validation you can specify the error message in validation tags. For example:
public class Movie
{
public int ID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name{ get; set; }
}
Then you can also add some DetailsProvider to get better details when calling the api:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(options =>
{
options.ModelMetadataDetailsProviders.Add(new NewtonsoftJsonValidationMetadataProvider());
}).AddNewtonsoftJson();
Validation in front end has some other scenarios. Take a look at
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-7.0
I'm using NancyFx model binding through the routing url and am trying to set up some validation for required properties. Class is as follows:
public class Query
{
[Required]
public string ClientId { get; set; }
public List<string> Customers { get; set; }
}
My route is as follows:
Get["/test?customers=c1,c2"] = args =>
{
var query = new Query(); // A
try
{
query = this.Bind<Query>(); // B
}
catch (ModelBindingException ex)
{
throw ex;
}
return db.Execute(Query);
};
}
At A, I expected there to be some sort of exception since ClientId is required but it is null when a new Query is initialized, but there is nothing.
Failing that, at B, I expected there to be some sort of error when I try to bind the Query object. Looking att he debugger, the query object's Customers property correctly has the expected value of "c1,c2". However, the ClientId in the query object is null, and there is no error. Am wondering what I can do to trigger an exception based on the fact that ClientId is required.
Check Nancy Wiki on validation
I am creating a test project in order to learn using asp.net 5 and the mvc 6 framework.
I have decided to create a simple webpage that each menu item comes from the database. To do so I have created a model like such
namespace TestTemplate.Models
{
public class SideMenuItem
{
public int Id { get; set; }
public string Level { get; set; }
public string Label { get; set; }
public string Link { get; set; }
}
}
Inside my Models folder I also have a file named `TestContext.cs'
namespace TestTemplate.Models
{
public class TestContext : DbContext
{
public DbSet<SideMenuItem> SideMenuItems { get; set; }
}
}
That is my EntityFramework DbContext class.
When trying to create a new SideMenu item by using a simple view with a form to adding all the needed data, then using my angular factory that looks like this
return $resource('/api/sidemenu/:id');
I get the error:
An exception of type 'Microsoft.Data.Entity.DbUpdateException' occurred in EntityFramework.Core.dll but was not handled in user code
Additional information: An error occurred while updating the entries. See the inner exception for details.
-->System.Data.SqlClient.SqlException: Invalid object name 'SideMenuItem'.
This error occurs on SideMenuController.cs where I define my API at the part where I am trying to Post the new item:
[HttpPost]
public IActionResult Post([FromBody]SideMenuItem sideMenuItem)
{
if (sideMenuItem.Id == 0)
{
_dbContext.SideMenuItems.Add(sideMenuItem);
_dbContext.SaveChanges(); // ERROR HERE.
return new ObjectResult(sideMenuItem);
}
else
{
var original = _dbContext.SideMenuItems.FirstOrDefault(m => m.Id == sideMenuItem.Id);
original.Level = sideMenuItem.Level;
original.Label = sideMenuItem.Label;
original.Link = sideMenuItem.Link;
_dbContext.SaveChanges();
return new ObjectResult(original);
}
}
I also should mention that before running the app i used
>dnx ef migration add initial
>dnx ef database update
I believe it has to do with me not creating my database correctly. Since I am not seeing any folder on my project that had anything to do with databases or migrations.
Why is it complaining that SideMenuItem is invalid, and how can I fix the issue?
After trying to create my database again, I noticed that I had a typo on my migration command, hence the database was not created.
The command should have been dnx ef migrations ... with an s.
A good starting point with all the commands can be found here.
I am learning about Data Access Object Design Patterns and implementing it with c# / oracle. However when I try to run the program I get an error.
I am simply trying to add data to my database, however I keep getting the following error:
An unhandled exception of type 'System.StackOverflowException' occurred in Test.dll
It happens at my ReviewGame getter and setter.
Would you be so kind to view my code and see where I am going wrong? I would appreciate any help.
public string ReviewGame { get; set; }
"insert into review values(review_seq.nextval," + 2+ "," + review.MemberId + ", '" +review.ReviewGame+ "')";
ReviewDao reviewDao = new ReviewDaoImp();
Review r = new Review();
r.reviewGame = textBox1.Text;
r.ToString();
reviewDao.addReview(r);
}
Your properties call themselves in their getter and setter. You need to use a backing field to store the data:
private string _reviewGame;
public string ReviewGame
{
get { return _reviewGame; }
set { _reviewGame = value; }
}
Or you can use an auto property:
public string ReviewGame { get; set; }
(Note that I also changed to property name to start with an upper case, which is according to conventions.)
I recently used ASP.Net MVC with DataAnnotations and was thinking of using the same approach for a Forms project but I'm not sure how to go about it.
I have set my attributes but they do not seem to get checked when I click Save.
UPDATE: I have used Steve Sanderson's approach which will check for attributes on my class and return a collection of errors like so:
try
{
Business b = new Business();
b.Name = "feds";
b.Description = "DFdsS";
b.CategoryID = 1;
b.CountryID = 2;
b.EMail = "SSDF";
var errors = DataAnnotationsValidationRunner.GetErrors(b);
if (errors.Any())
throw new RulesException(errors);
b.Save();
}
catch(Exception ex)
{
}
What do you think of this approach?
Here's a simple example. suppose you have an object like the following
using System.ComponentModel.DataAnnotations;
public class Contact
{
[Required(AllowEmptyStrings = false, ErrorMessage = "First name is required")]
[StringLength(20, MinimumLength = 5, ErrorMessage = "First name must be between 5 and 20 characters")]
public string FirstName { get; set; }
public string LastName { get; set; }
[DataType(DataType.DateTime)]
public DateTime Birthday { get; set; }
}
And suppose we have a method that creates an instance of this class and tries to validate its properties, as listed below
private void DoSomething()
{
Contact contact = new Contact { FirstName = "Armin", LastName = "Zia", Birthday = new DateTime(1988, 04, 20) };
ValidationContext context = new ValidationContext(contact, null, null);
IList<ValidationResult> errors = new List<ValidationResult>();
if (!Validator.TryValidateObject(contact, context, errors,true))
{
foreach (ValidationResult result in errors)
MessageBox.Show(result.ErrorMessage);
}
else
MessageBox.Show("Validated");
}
The DataAnnotations namespace is not tied to the MVC framework so you can use it in different types of applications. the code snippet above returns true, try to update the property values to get validation errors.
And make sure to checkout the reference on MSDN: DataAnnotations Namespace
Steve's example is a bit dated (though still good). The DataAnnotationsValidationRunner that he has can be replaced by the System.ComponentModel.DataAnnotations.Validator class now, it has static methods for validating properties and objects which have been decorated with DataAnnotations attributes.
I found a decent example of using DataAnnotations with WinForms using the Validator class, including tying into the IDataErrorInfo interface so ErrorProvider can display the results.
Here is the link.
DataAnnotations Validation Attributes in Windows Forms
If you use newest versions of Entity Framework you can use this cmd to get a list of your errors if existing:
YourDbContext.Entity(YourEntity).GetValidationResult();