asp.net-mvc MVC 5 种子用户和角色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19280527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVC 5 Seed Users and Roles
提问by MrBeanzy
I have been playing about with the new MVC 5, I have a few models, controller and views setup using code first migrations.
我一直在玩新的 MVC 5,我使用代码优先迁移设置了一些模型、控制器和视图。
My question is how do I seed users and roles? I currently seed some reference data in my Seed method in Configuration.cs. But it looks to me that the user and roles tables are not created until something first hits the AccountController.
我的问题是如何播种用户和角色?我目前在 Configuration.cs 的 Seed 方法中播种了一些参考数据。但在我看来,用户和角色表是在第一次点击 AccountController 之前创建的。
I currently have two connection strings so I can separate my data from my authentication into different databases.
我目前有两个连接字符串,所以我可以将我的数据从我的身份验证中分离到不同的数据库中。
How can I get the user, roles, etc tables populate along with my others? And not when the account controller is hit?
如何让用户、角色等表与我的其他表一起填充?而不是当帐户控制器被击中时?
回答by Valin
Here is example of usual Seed approach:
以下是常用种子方法的示例:
protected override void Seed(SecurityModule.DataContexts.IdentityDb context)
{
if (!context.Roles.Any(r => r.Name == "AppAdmin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "AppAdmin" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "founder"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser {UserName = "founder"};
manager.Create(user, "ChangeItAsap!");
manager.AddToRole(user.Id, "AppAdmin");
}
}
I used package-manager "update-database". DB and all tables were created and seeded with data.
我使用了包管理器“更新数据库”。数据库和所有表都被创建并植入了数据。
回答by Kevin
It's a small addition, but to anyone having the "UserId not found." message when trying to seed: (Tom Regan had this question in the comments, and I was stuck on it myself for a while)
这是一个小小的补充,但对于“找不到用户 ID”的任何人来说。尝试播种时的消息:(汤姆·里根(Tom Regan)在评论中提出了这个问题,我自己也被困了一段时间)
This means that the manager.Create(user, "ChangeItAsap!") was not successful. This might have a different reason, but for me it was because my password was not succeeding its validation.
这意味着 manager.Create(user, "ChangeItAsap!") 没有成功。这可能有不同的原因,但对我来说这是因为我的密码没有通过验证。
I had a custom passwordvalidator, which was not being called when seeding the database, so the validation rules i was used to (minlength 4 instead of default 6) did not apply. Make sure your password (and all other fields for that matter) is passing validation.
我有一个自定义的密码验证器,在为数据库做种时没有调用它,所以我习惯的验证规则(最小长度 4 而不是默认的 6)不适用。确保您的密码(以及与此相关的所有其他字段)通过验证。
回答by Vasil Valchev
This is my method base on Valin answer, I have added roles in db and added password for user. This code is placed in Seed()method in Migrations>Configurations.cs.
这是我基于 Valin 答案的方法,我在 db 中添加了角色并为用户添加了密码。此代码放置Seed()在 Migrations>Configurations.cs中的方法中。
// role (Const.getRoles() return string[] whit all roles)
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
for (int i = 0; i < Const.getRoles().Length; i++)
{
if (RoleManager.RoleExists(Const.getRoles()[i]) == false)
{
RoleManager.Create(new IdentityRole(Const.getRoles()[i]));
}
}
// user
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var PasswordHash = new PasswordHasher();
if (!context.Users.Any(u => u.UserName == "[email protected]"))
{
var user = new ApplicationUser
{
UserName = "[email protected]",
Email = "[email protected]",
PasswordHash = PasswordHash.HashPassword("123456")
};
UserManager.Create(user);
UserManager.AddToRole(user.Id, Const.getRoles()[0]);
}
回答by Mr Tangjai
Here i have an very easy,clean and smooth solution.
在这里,我有一个非常简单、干净和流畅的解决方案。
protected override void Seed(UserContext context)
{
//Step 1 Create the user.
var passwordHasher = new PasswordHasher();
var user = new IdentityUser("Administrator");
user.PasswordHash = passwordHasher.HashPassword("Admin12345");
user.SecurityStamp = Guid.NewGuid().ToString();
//Step 2 Create and add the new Role.
var roleToChoose = new IdentityRole("Admin");
context.Roles.Add(roleToChoose);
//Step 3 Create a role for a user
var role = new IdentityUserRole();
role.RoleId = roleToChoose.Id;
role.UserId = user.Id;
//Step 4 Add the role row and add the user to DB)
user.Roles.Add(role);
context.Users.Add(user);
}
回答by Shimmy Weitzhandler
protected override void Seed(ApplicationDbContext context)
{
SeedAsync(context).GetAwaiter().GetResult();
}
private async Task SeedAsync(ApplicationDbContext context)
{
var userManager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context));
var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole, int, ApplicationUserRole>(context));
if (!roleManager.Roles.Any())
{
await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AdminRoleName });
await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AffiliateRoleName });
}
if (!userManager.Users.Any(u => u.UserName == "shimmy"))
{
var user = new ApplicationUser
{
UserName = "shimmy",
Email = "[email protected]",
EmailConfirmed = true,
PhoneNumber = "0123456789",
PhoneNumberConfirmed = true
};
await userManager.CreateAsync(user, "****");
await userManager.AddToRoleAsync(user.Id, ApplicationRole.AdminRoleName);
}
}
回答by FatalMan
write this code in your Migration Configuration.
在您的迁移配置中编写此代码。
note: Use ApplicationDbContext in Configuration Class.
注意:在配置类中使用 ApplicationDbContext。
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
context.Roles.AddOrUpdate(p =>
p.Id,
new IdentityRole { Name = "Admins"},
new IdentityRole { Name = "PowerUsers" },
new IdentityRole { Name = "Users" },
new IdentityRole { Name = "Anonymous" }
);
}
}
回答by MrBeanzy
Looks like they changes the way authentication works in MVC5, changed my Global.asax.cs to the following did the trick!
看起来他们改变了 MVC5 中身份验证的工作方式,将我的 Global.asax.cs 更改为以下内容即可!
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Threading.Tasks;
using MvcAuth.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System.Threading;
using Microsoft.AspNet.Identity.EntityFramework;
namespace MvcAuth
{
public class MvcApplication : System.Web.HttpApplication
{
async Task<bool> AddRoleAndUser()
{
AuthenticationIdentityManager IdentityManager = new AuthenticationIdentityManager(
new IdentityStore(new ApplicationDbContext()));
var role = new Role("Role1");
IdentityResult result = await IdentityManager.Roles.CreateRoleAsync(role, CancellationToken.None);
if (result.Success == false)
return false;
var user = new ApplicationUser() { UserName = "user1" };
result = await IdentityManager.Users.CreateLocalUserAsync(user, "Password1");
if (result.Success == false)
return false;
result = await IdentityManager.Roles.AddUserToRoleAsync(user.Id, role.Id, CancellationToken.None);
return result.Success;
}
protected async void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
bool x = await AddRoleAndUser();
}
}
}

