尝试为 Asp.Net mvc 5 EntityFramework 6 中的用户和角色播种数据时出错
error while trying to seed data for user and role in Asp.Net mvc 5 EntityFramework 6
当我尝试使用用户和角色的种子数据更新数据库时,出现 "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." 错误。角色已创建,我可以在数据库 table 中看到它们,但没有创建具有管理员角色的用户。此外,角色未显示在创建和编辑用户视图中。
创建用户的ViewModel:
public class InsertUser
{
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "First Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]//requires the first character to be upper case and the remaining characters to be alphabetical
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "Last Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("Password", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public List<CheckBoxItem> Roles { get; set; }
}
public class CheckBoxItem
{
public string Id { get; set; }
public string Text { get; set; }
public bool Checked { get; set; }
}
编辑用户的ViewModel:
public class EditUser
{
public EditUser()
{
Roles = new List<CheckBoxItem>();
}
[Key]
public string Id { get; set; }
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "First Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "Last Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
public List<CheckBoxItem> Roles { get; set; }
}
我创建了自己的 ViewModel 来编辑和创建用户,因为场景是这样的,用户必须从管理员创建,所以为了保持分离,我创建了自己的 ViewModel,这与 AccountViewModel 不同。但除此之外,可以创建一个简单的用户,就像在 ASp.Net MVC 中开箱即用一样,具有个人用户帐户、电子邮件、用户名和密码。管理员有权添加更多详细信息,例如名字和姓氏并分配角色。
创建(和编辑)视图:
...
<div class="form-group">
@Html.LabelFor(model => model.Roles, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.CheckBoxListFor(model => model.Roles
, model => model.Roles
, model => model.Id
, model => model.Text
, model => model.Checked
, model => new { @class = "checkbox-inline" })
</div>
</div>
...
我为 ChechBoxListFor html 助手安装了 MvcCheckBoxList nuget。
创建用户的获取操作方法:
public ActionResult Create()
{
var items = new InsertUser();
items.Roles = _roleManager.Roles.Select(x => new CheckBoxItem { Id = x.Id, Text = x.Name, Checked = false }).ToList();
return View(items);
}
和配置class,种子方法:
if (!context.Roles.Any(r => r.Name == "admin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "admin" };
manager.Create(role);
}
if (!context.Roles.Any(r => r.Name == "user"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "user" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "admin"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser { UserName = "admin", Email="admin@email.com" };
manager.Create(user, "password123");
manager.AddToRole(user.Id, "admin");
}
仅供参考,我将密码设置为至少需要 6 个字母,我评论了其他请求,如 RequiredLowercase、RequieredUppercase、RequireNonLetterOrDigit、RequireDigit。
那么谁能帮我解决这个问题,创建管理员用户并在编辑和创建视图中显示角色?
仅当数据库架构与 EntityModel 不同时才会调用种子方法。看起来你的种子方法可能没有被执行。
在种子方法中,if 是您创建角色的地方,将 IdentityRole
替换为 ApplicationRole
当我尝试使用用户和角色的种子数据更新数据库时,出现 "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." 错误。角色已创建,我可以在数据库 table 中看到它们,但没有创建具有管理员角色的用户。此外,角色未显示在创建和编辑用户视图中。
创建用户的ViewModel:
public class InsertUser
{
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "First Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]//requires the first character to be upper case and the remaining characters to be alphabetical
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "Last Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("Password", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public List<CheckBoxItem> Roles { get; set; }
}
public class CheckBoxItem
{
public string Id { get; set; }
public string Text { get; set; }
public bool Checked { get; set; }
}
编辑用户的ViewModel:
public class EditUser
{
public EditUser()
{
Roles = new List<CheckBoxItem>();
}
[Key]
public string Id { get; set; }
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "First Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "Last Name")]
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$", ErrorMessage = "The {0} must start with upper letter and contain only alphabetical letters")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
public List<CheckBoxItem> Roles { get; set; }
}
我创建了自己的 ViewModel 来编辑和创建用户,因为场景是这样的,用户必须从管理员创建,所以为了保持分离,我创建了自己的 ViewModel,这与 AccountViewModel 不同。但除此之外,可以创建一个简单的用户,就像在 ASp.Net MVC 中开箱即用一样,具有个人用户帐户、电子邮件、用户名和密码。管理员有权添加更多详细信息,例如名字和姓氏并分配角色。
创建(和编辑)视图:
...
<div class="form-group">
@Html.LabelFor(model => model.Roles, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.CheckBoxListFor(model => model.Roles
, model => model.Roles
, model => model.Id
, model => model.Text
, model => model.Checked
, model => new { @class = "checkbox-inline" })
</div>
</div>
...
我为 ChechBoxListFor html 助手安装了 MvcCheckBoxList nuget。
创建用户的获取操作方法:
public ActionResult Create()
{
var items = new InsertUser();
items.Roles = _roleManager.Roles.Select(x => new CheckBoxItem { Id = x.Id, Text = x.Name, Checked = false }).ToList();
return View(items);
}
和配置class,种子方法:
if (!context.Roles.Any(r => r.Name == "admin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "admin" };
manager.Create(role);
}
if (!context.Roles.Any(r => r.Name == "user"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "user" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "admin"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser { UserName = "admin", Email="admin@email.com" };
manager.Create(user, "password123");
manager.AddToRole(user.Id, "admin");
}
仅供参考,我将密码设置为至少需要 6 个字母,我评论了其他请求,如 RequiredLowercase、RequieredUppercase、RequireNonLetterOrDigit、RequireDigit。
那么谁能帮我解决这个问题,创建管理员用户并在编辑和创建视图中显示角色?
仅当数据库架构与 EntityModel 不同时才会调用种子方法。看起来你的种子方法可能没有被执行。
在种子方法中,if 是您创建角色的地方,将 IdentityRole
替换为 ApplicationRole