0
votes

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; }
    }
2
First of all you should See EntityValidationErrors property for more detailsSzer
ModelState.IsValid indicates that data in RegisterViewModel is valid. But doesn't indicate that data in your User entity is valid.haim770
Normally this error will relate to your model field not inserted properly.I suggest you look into this.Basically you do a try-catch and the error message will be displayed indicating what is the problem that prevent you from inserting to db.Shawn Yan
I saw that question earlier, and tried doing the answer about the watch, but I will try using a try-catch and see how it worksbankey
1. Make sure your catch looks like this catch (System.Data.Entity.Validation.DbEntityValidationException ex) {/* logging and then throw */ }. 2. Put a break point in the catch. 3. Inspect object ex. 4. Inspect property EntityValidationErrors of object exIgor

2 Answers

0
votes

Fix: When I looked up a tutorial about MVC it asked em to create a partial class and a meta class. That was for code first I believe, which basically made it a new field that my database didn't have a spot for, and I am using database first. So I removed the deleted the partial class for User and it stopped making ConfirmPassword an actual field in the database.

Don't know the real works of it, or if what I said makes sense, but I hope this helps someone eventually.

0
votes

Remove

[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$",
ErrorMessage = "Please enter a valid email")]

from RegisterViewModel