Я новичок в ASP.NET MVC5
.
Мое решение проекта имеет структуру, описанную в ASP.NET MVC5 Pro:
Solution
-Project.Domain --- C# Class Library
-Project.WebUI --- Empty ASP.Net MVC Project Template
-Project.UnitTests
И я хочу использовать в нем ASP Identity 2.0
.
В Project.Domain у меня есть Concrete
(контексты, их инициализаторы) и Entities
(модели данных).
Я установил Identity 2.0 Samples
как описано здесь.
Я разделил файл IdentityModels.cs
в ApplicationDbContext.cs
и ApplicationUser.cs
и поместил их в слоты Concrete
и Entities
соответственно.
Также в Concrete
foldier у меня есть EFDbContext.cs
- отдельно от контекста ApplicationDbContext
(они используют одно и то же соединение с базой данных).
Я хотел сохранить класс AppicationDbInitializer
(из Project.WebUI\App_Start\IdentityConfig.cs
) в Project.Domain
поскольку ApplicationDbContext
содержит статический конструктор, который устанавливает ApplicationDbInitializer
, но потом выяснилось, что Project.Domain
и Project.WebUI
имеют циклическую зависимость, поэтому я решил не переместить его и установить инициализатор базы данных в Global.asax.cs
из Project.WebUI
.
Затем начались проблемы. По некоторым причинам метод ApplicationDbInitializer.Seed
не работает и role "Admin"
не создается. Затем я решил попробовать выполнить миграцию. Я включил миграции в Project.Domain
(как описано здесь), а для реализации Seed
мне нужен доступ к классам из IdentityConfig.cs(ApplicationUserManager and ApplicationRoleManager)
из Project.WebUI
. К сожалению, он снова создаст циклическую зависимость.
Мой вопрос в том, что делать: как правильно разделить решение на проекты и найти файлы Identity 2.0
? И почему метод Seed
из ApplicationDbInitilizer
не работает?
Я думаю, мы пытаемся сделать то же самое Соня, и я нахожусь в той же лодке, что и ты. Я наполним вас тем, что я пробовал.
Во-первых, вы можете исправить циклическую зависимость, перемещая ApplicationDbInitializer в метод Application_Start и вызывая Database.SetInitializer.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
Это позволяет сохранить ApplicationDbContext и ApplicationUser в Домене, оставив ApplicationDbInitializer в проекте WebUI.
Во-вторых, я прочитал предыдущее сообщение, в котором говорилось, что не использует методы GetOwinContext для получения userManager и roleManager, но не уверен, насколько хороша идея. Но, по крайней мере, это позволило мне сделать еще один шаг вперед.
Функция Moving Identity 2.0 для класса репозитория
public static void InitializeIdentityForEf(ApplicationDbContext context) {
// var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
// var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
// Since we needed to move this class into the Domain namespace, we have to do the Owin differently
var roleStore = new RoleStore<IdentityRole>(context);
var roleManager = new RoleManager<IdentityRole>(roleStore);
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
Семя не заполняется, когда я делаю "Update-Database", но он пытается запустить, когда я запускаю веб-сайт и пытаюсь зарегистрировать пользователя. Но я получаю сообщение об ошибке
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
на этой линии
var result = await UserManager.CreateAsync(user, model.Password);