Доступ к UserManager за пределами AccountController
Я пытаюсь установить значение столбца в таблице aspnetuser
с другого контроллера (не accountcontroller
). Я пытался получить доступ к UserManager
, но я не могу понять, как это сделать.
До сих пор я пробовал следующее в контроллере, в котором я хочу использовать его:
ApplicationUser u = UserManager.FindById(User.Identity.GetUserId());
u.IsRegComplete = true;
UserManager.Update(u);
Это не скомпилируется (я думаю, потому что UserManager
не был создан экземпляр контроллера)
Я также попытался создать открытый метод в accountcontroller
, чтобы принять значение, которое я хочу изменить, и сделать его там, но я не могу понять, как его вызвать.
public void setIsRegComplete(Boolean setValue)
{
ApplicationUser u = UserManager.FindById(User.Identity.GetUserId());
u.IsRegComplete = setValue;
UserManager.Update(u);
return;
}
Как вы получаете доступ и редактируете данные пользователя за пределами Контроллера учетных записей?
UPDATE:
Я попытался создать экземпляр UserManager в другом контроллере следующим образом:
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
ApplicationUser u = userManager.FindById(User.Identity.GetUserId());
Я выполнил проект (немного взволнован), но когда я запустил код, я получил следующую ошибку:
Additional information: The entity type ApplicationUser is not part of the model for the current context.
ОБНОВЛЕНИЕ 2:
Я переместил эту функцию в IdentityModel (не спрашивайте, чтобы я сжимал здесь соломинку):
public class ApplicationUser : IdentityUser
{
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;
}
public Boolean IsRegComplete { get; set; }
public void SetIsRegComplete(string userId, Boolean valueToSet)
{
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
ApplicationUser u = new ApplicationUser();
u = userManager.FindById(userId);
u.IsRegComplete = valueToSet;
return;
}
}
Однако я все еще получаю следующее:
The entity type ApplicationUser is not part of the model for the current context.
В IdentitiesModels.cs также есть следующий класс:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Что я здесь делаю неправильно? Похоже, я полностью лаем неправильное дерево. Все, что я пытаюсь сделать, это обновить столбец таблицы aspnetuser от действия другого контроллера (т.е. Не AccountsController).
Ответы
Ответ 1
Если вы используете шаблон проекта по умолчанию, UserManager
создается следующим образом:
В файле Startup.Auth.cs есть такая строка:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
что делает OWIN-конвейер экземпляром экземпляра ApplicationUserManager
каждый раз, когда запрос поступает на сервер. Вы можете получить этот экземпляр из конвейера OWIN, используя следующий код внутри контроллера:
Request.GetOwinContext().GetUserManager<ApplicationUserManager>()
Если вы внимательно посмотрите на свой класс AccountController
, вы увидите следующие фрагменты кода, которые делают возможным доступ к ApplicationUserManager
:
private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
Обратите внимание, что если вам нужно создать экземпляр класса ApplicationUserManager
, вам нужно использовать статический метод ApplicationUserManager.Create
, чтобы у вас были соответствующие настройки и настройки, применяемые к нему.
Ответ 2
Если вам нужно получить экземпляр UserManager в другом Контроллере, просто добавьте его параметр в конструктор Controller, подобный этому
public class MyController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
public MyController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;;
}
}
Но я должен получить UserManager в классе, который не является контроллером!
Любая помощь будет оценена.
UPDATE
Я рассматриваю, что вы используете core asp.net
Ответ 3
Я столкнулся с этой же проблемой и модифицировал свой код, чтобы передать ссылку на класс UserManager из контроллера на модель:
//snippet from Controller
public async Task<JsonResult> UpdateUser(ApplicationUser applicationUser)
{
return Json(await UserIdentityDataAccess.UpdateUser(UserManager, applicationUser));
}
//snippet from Data Model
public static async Task<IdentityResult> UpdateUser(ApplicationUserManager userManager, ApplicationUser applicationUser)
{
applicationUser.UserName = applicationUser.Email;
var result = await userManager.UpdateAsync(applicationUser);
return result;
}