Пользователи и роли семян MVC 5
Я играл с новым MVC 5, у меня есть несколько моделей, настройка контроллера и просмотров с использованием первых миграций кода.
Мой вопрос в том, как я могу посеять пользователей и роли? В настоящее время я использую некоторые ссылочные данные в методе Seed в Configuration.cs. Но мне кажется, что таблицы пользователей и ролей не создаются до тех пор, пока что-то сначала не попадет на AccountController.
В настоящее время у меня есть две строки подключения, поэтому я могу отделить свои данные от моей аутентификации в разных базах данных.
Как я могу заполнить таблицы пользователей, ролей и т.д. вместе с моими другими? И не тогда, когда на контроллер аккаунта попал?
Ответы
Ответ 1
Вот пример обычного подхода Seed:
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");
}
}
Я использовал пакет-менеджер "update-database". DB и все таблицы были созданы и засеяны данными.
Ответ 2
Это небольшое дополнение, но для любого, у кого "UserId не найден". сообщение при попытке посеять: (Том Реган имел этот вопрос в комментариях, и я застрял на нем сам на некоторое время)
Это означает, что manager.Create(пользователь, "ChangeItAsap!" ) не был успешным.
Это может иметь другую причину, но для меня это было потому, что мой пароль не преуспел в его проверке.
У меня был пользовательский пароль-валидатор, который не вызывался при посеве базы данных, поэтому правила проверки я были использованы (minlength 4 вместо default 6) не применялись. Убедитесь, что ваш пароль (и все другие поля, если на то пошло) проходит проверку.
Ответ 3
Это моя методическая база по ответу Валина, я добавил роли в 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]);
}
Ответ 4
Здесь у меня очень простое, чистое и гладкое решение.
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);
}
Ответ 5
То, что я делаю, это создать другой асинхронный идеал и называть его синхронно, отлично работает для меня.
protected override void Seed(ApplicationDbContext context)
{
Task.Run(async () => { await SeedAsync(context); }).Wait();
}
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);
}
}
Ответ 6
Похоже, что они меняют способ аутентификации в 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();
}
}
}
Ответ 7
запишите этот код в своей конфигурации миграции.
примечание: используйте 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.Name,
new IdentityRole { Name = "Admins", Id = "1"},
new IdentityRole { Name = "PowerUsers", Id = "2" },
new IdentityRole { Name = "Users", Id = "3" },
new IdentityRole { Name = "Anonymous", Id = "4" }
);
}
}