0

In my Seed() method of Configuration.cs, I'm getting some errors when adding data:

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

StackTrace

at System.Data.Entity.Internal.InternalContext.SaveChanges()

My Configuration.cs file with seed data:

namespace MarginWorkbenchNG.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

internal sealed class Configuration : DbMigrationsConfiguration<MarginWorkbenchNG.Models.ApplicationDbContext>
{
	public Configuration()
	{
		AutomaticMigrationsEnabled = true;
		AutomaticMigrationDataLossAllowed = true;   // added - BM:
		ContextKey = "MarginWorkbenchNG.Models.ApplicationDbContext";
	}

	protected override void Seed(MarginWorkbenchNG.Models.ApplicationDbContext context)
	{

		var hasher = new PasswordHasher();

		// **** Causing "Validation failed" errors on line 80 of AccountController.cs ****
		context.Roles.AddOrUpdate(
			new IdentityRole { Name = "SystemAdministrator" }                
		);
		context.Users.AddOrUpdate(                
			new Models.ApplicationUser { Company = "ICAP", EmailConfirmed = true, FirstName = "Admin", LastName = "Demo", UserName = "[email protected]", Email = "[email protected]", PasswordHash = hasher.HashPassword("test123") },
			new Models.ApplicationUser { Company = "ICAP", EmailConfirmed = true, FirstName = "Trader", LastName = "Demo", UserName = "[email protected]", Email = "[email protected]", PasswordHash = hasher.HashPassword("test123") }
		);

		context.SaveChanges();

	}
}
}

I have made a couple of minor changes to my ApplicationUser class in IdentityModels.cs, and I can certainly see the table schema changes any time I modify this class (i.e. I have auto-migration set to true). However, Seed() method fails.

public class ApplicationUser : IdentityUser
{
  // added Company, Name to profile - BM:
  public string Company { get; set; }
  public string FirstName { get; set; }
  public string LastName{ get; set; }        

  public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
  {
    // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
    var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
    // Add custom user claims here
    return userIdentity;
  }
}

FYI: At some point, when the AppNetUsers table was empty, the seed data was successful.

However, it's totally inconsistent now. I've deleted the records in AppNetUsers, and yet the Seed() method is stil failing. I don't understand.

**** UPDATE **** If I change the DB name in my web.config file, I can force it to create a brand new DB - and the seed() data works fine !

 <connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=MyDevBox;Initial Catalog=TestDB2;Integrated Security=True" providerName="System.Data.SqlClient" />  

However, I still don't understand the exceptions in my Seed() method above when I try to RE-CREATE the DB ?

thank you, Bob

4
  • Can you include the console output that happens when you try to seed (and it fails)? And include your Seed method. Commented Mar 9, 2016 at 18:54
  • 2
    Please provide the failing source code in the seed() method? Commented Mar 9, 2016 at 18:56
  • @toddmo, yes of course. I forgot the actual seed data. Commented Mar 9, 2016 at 19:56
  • 1
    Yes, use RoleManager & UserManager. On another note, when you use AddOrUpdate you should supply the field to check for existance: stackoverflow.com/questions/10007351/… Commented Mar 9, 2016 at 20:28

1 Answer 1

2

Don't add Identity objects directly to your DbContext use role manager and user manager instead:

protected override void Seed(MarginWorkbenchNG.Models.ApplicationDbContext context)
{
    var userManager = new ApplicationUserManager(new UserStore<Models.ApplicationUser>(context));
    var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

    if (!roleManager.RoleExists("SystemAdministrator"))
        roleManager.Create(new IdentityRole("SystemAdministrator"));

    var adminUser = userManager.FindByName("[email protected]");
    if (adminUser == null)
    {
         adminUser = new ApplicationUser
         {
             Company = "ICAP", 
             EmailConfirmed = true, 
             FirstName = "Admin", 
             LastName = "Demo", 
             UserName = "[email protected]", 
             Email = "[email protected]"
         };
         userManager.Create(adminUser,"thePassword");
    }
    // adding roles to the user if necessary 
    if (!userManager.IsInRole(adminUser.Id, "SystemAdministrator"))
        userManager.AddToRole(adminUser.Id, "SystemAdministrator");

}
Sign up to request clarification or add additional context in comments.

13 Comments

I edited the post to show <Models.ApplicationUser> , based on c# suggested change.
I read that the AddOrUpdate() method would take care of checking whether the records exists or not. Perhaps not in the context of users and roles ?
It checks but you have to say which property is unique and must be checked, Also it would much better to let user manager create your user and add necessary logic then send it to context.
I've accepted your edit. But you could add relevant namespace to prevent the error.
put adminUser = userManager.FindByName("[email protected]"); statement again after userMannager.Create(.. method to fetch created method from db again.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.