New to MVC. When I try to add a user to the database using Entity Framework Database First I get this exception:
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.
This is the code:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Index(RegisterViewModel account) { if (ModelState.IsValid) { using (db) { bool duplicate = db.Users.Any(a => a.UserName == account.UserName); if (duplicate) { ModelState.AddModelError("", "Username already exists in database!"); } else { db.Users.Add(new StoreFront.Models.User { UserName = account.UserName, Password = account.Password, EmailAddress = account.EmailAddress, IsAdmin = false, DateCreated = DateTime.Now }); db.SaveChanges(); ModelState.Clear(); ModelState.AddModelError("RegisterSuccess", "Successfully registered!"); } } } return View(); }
I have validation in my RegisterViewModel for all fields, and when I debug, IsValid = true, otherwise it wouldn't run anyway. Any help would be greatly appreciated...I have been struggling with this for a while.
P.S. Yes the password is currently being stored as a string, this is just a test project that won't be used in the real world.
EDIT: Added Models:
User Model from database:
public partial class User { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public User() { this.Addresses = new HashSet<Address>(); this.Orders = new HashSet<Order>(); this.ShoppingCarts = new HashSet<ShoppingCart>(); } public int UserID { get; set; } public string UserName { get; set; } public string Password { get; set; } public string EmailAddress { get; set; } public Nullable<bool> IsAdmin { get; set; } public Nullable<System.DateTime> DateCreated { get; set; } public string CreatedBy { get; set; } public Nullable<System.DateTime> DateModified { get; set; } public string ModifiedBy { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Address> Addresses { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<Order> Orders { get; set; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public virtual ICollection<ShoppingCart> ShoppingCarts { get; set; } }
Partial Model to add ConfirmPassword:
namespace StoreFront.Models { [MetadataType(typeof(RegisterViewModel))] public partial class User { [DisplayName("Confirm Password")] [DataType(DataType.Password)] [Compare("Password", ErrorMessage = "Passwords must match")] public string ConfirmPassword { get; set; } } }
RegisterViewModel:
public class RegisterViewModel { public int UserID { get; set; } [DisplayName("Username")] [Required(ErrorMessage = "Username is required")] public string UserName { get; set; } [DisplayName("Password")] [DataType(DataType.Password)] [Required(ErrorMessage = "Password is required")] public string Password { get; set; } [DisplayName("Confirm Password")] [DataType(DataType.Password)] [Compare("Password", ErrorMessage = "Passwords must match")] public string ConfirmPassword { get; set; } [DisplayName("Email")] [Required(ErrorMessage = "Email is required")] [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$", ErrorMessage = "Please enter a valid email")] public string EmailAddress { get; set; } public Nullable<bool> IsAdmin { get; set; } public Nullable<System.DateTime> DateCreated { get; set; } }
See EntityValidationErrors property for more details
ModelState.IsValid
indicates that data inRegisterViewModel
is valid. But doesn't indicate that data in yourUser
entity is valid.try-catch
and the error message will be displayed indicating what is the problem that prevent you from inserting to db.catch (System.Data.Entity.Validation.DbEntityValidationException ex) {/* logging and then throw */ }
. 2. Put a break point in the catch. 3. Inspect objectex
. 4. Inspect propertyEntityValidationErrors
of objectex