Обновление пользовательских данных - ASP.NET идентичность



я добавил пользовательские поля к ApplicationUser класс

Также я создал форму, через которую пользователь может вводить/редактировать поля.

Однако по какой-то причине я не могу обновить поля в базе данных.



[HttpPost]
[ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(EditProfileViewModel model)
{
if (ModelState.IsValid)
{
// Get the current application user
var user = User.Identity.GetApplicationUser();

// Update the details
user.Name = new Name { First = model.FirstName, Last = model.LastName, Nickname = model.NickName };
user.Birthday = model.Birthdate;

// This is the part that doesn't work
var result = await UserManager.UpdateAsync(user);

// However, it always succeeds inspite of not updating the database
if (!result.Succeeded)
{
AddErrors(result);
}
}

return RedirectToAction("Manage");
}


моя проблема похожа на пользовательские свойства Mvc5 ApplicationUser, но, похоже, используется более старая версия Identity, потому что класс IdentityManager, похоже, не существует.



может кто-то направить меня о том, как обновить User информация в базе данных?



обновление:
Если я включаю все поля в форму регистра, все значения сохраняются в соответствующем поле в новой записи Users таблицы из базы данных.



Я не знаю, чтобы вносить изменения в поля существующего пользователя (строка users таблица). UserManager.UpdateAsync(user) не работает.



также обратите внимание, что моя проблема больше ориентирована на личность, чем EntityFramework

818   11  

11 ответов:

ОК... Я часами пытался понять, почему userManager.updateAsync не будет сохраняться пользовательские данные, которые мы редактируем ... пока я не пришел к следующему выводу:

путаница возникает из-за того, что мы создаем UserManager в одну строчку:

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext()));

...тогда мы используем manager.UpdateAsync( user ); но это обновит пользователя в контексте, а затем нам нужно будет сохранить изменения в dbcontext идентификатора. Итак, вопрос в том, как получить идентификатор DBcontext в самом простом путь.

чтобы решить эту проблему, мы не должны создать UserManager в одну строку ... и вот как я это делаю:

var store = new UserStore<ApplicationUser>(new MyDbContext());
var manager = new UserManager(store);

затем после обновления пользователем по телефону

manager.UpdateAsync(user);

тогда вы идете в контекст

var ctx = store.context;

затем

ctx.saveChanges();

wahooooooo...упорствовал:)

надеюсь, что это поможет кому-то, кто вытащил свои волосы в течение нескольких часов :P

Если вы оставите любое из полей для ApplicationUser или IdentityUser null обновление вернется как успешное, но не будет сохранять данные в базе данных.

пример решения:

ApplicationUser model = UserManager.FindById(User.Identity.GetUserId())

добавить недавно обновленные поля:

model.Email = AppUserViewModel.Email;
model.FName = AppUserViewModel.FName;
model.LName = AppUserViewModel.LName;
model.DOB = AppUserViewModel.DOB;
model.Gender = AppUserViewModel.Gender;

Вызов UpdateAsync

IdentityResult result = await UserManager.UpdateAsync(model);

Я проверил это, и это работает.

контекст OWIN позволяет получить контекст БД. Кажется, до сих пор работает нормально, и в конце концов, я получил идею от класса ApplciationUserManager, который делает то же самое.

    internal void UpdateEmail(HttpContext context, string userName, string email)
    {
        var manager = context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = manager.FindByName(userName);
        user.Email = email;
        user.EmailConfirmed = false;
        manager.Update(user);
        context.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
    }

UserManager не работал, и как писал @Kevin Junghans,

UpdateAsync просто фиксирует обновление в контексте, вам все равно нужно сохранить контекст для его фиксации в базе данных

вот быстрое решение (до появления новых функций в ASP.net identity v2) я использовал в веб-формах projetc. Элемент

class AspNetUser :IdentityUser

был перенесен из SqlServerMembership aspnet_Users. И контекст определяется:

public partial class MyContext : IdentityDbContext<AspNetUser>

приношу свои извинения отражение и синхронный код--если вы помещаете это в асинхронный метод, используйте await для асинхронных вызовов и удаления задач и ожидания()s. arg, props, содержит имена свойств для обновления.

 public static void UpdateAspNetUser(AspNetUser user, string[] props)
 {
     MyContext context = new MyContext();
     UserStore<AspNetUser> store = new UserStore<AspNetUser>(context);
     Task<AspNetUser> cUser = store.FindByIdAsync(user.Id); 
     cUser.Wait();
     AspNetUser oldUser = cUser.Result;

    foreach (var prop in props)
    {
        PropertyInfo pi = typeof(AspNetUser).GetProperty(prop);
        var val = pi.GetValue(user);
        pi.SetValue(oldUser, val);
    }

    Task task = store.UpdateAsync(oldUser);
    task.Wait();

    context.SaveChanges();
 }

У меня также были проблемы с использованием UpdateAsync при разработке версии SimpleSecurity который использует ASP.NET личность. Например, я добавил функцию для сброса пароля, которая должна была добавить маркер сброса пароля к пользовательской информации. Сначала я попытался использовать UpdateAsync, и он получил те же результаты, что и вы. Я закончил тем, что обернул объект user в шаблон репозитория и заставил его работать. Вы можете посмотреть на проект SimpleSecurity для примера. После работа с ASP.NET Identity more (документация все еще не существует) я думаю, что UpdateAsync просто фиксирует обновление в контексте, вам все равно нужно сохранить контекст для его фиксации в базе данных.

Я пробовал функции таким же образом, и когда я называю UserManager.Updateasync метод это удается, но нет обновления в базе данных. Потратив некоторое время я нашел другое решение для обновления данных aspnetusers таблица, которая выглядит следующим образом:

1) вам нужно создать UserDbContext класс, который наследует от IdentityDbContext класс такой:

public class UserDbContext:IdentityDbContext<UserInfo>
{
    public UserDbContext():
        base("DefaultConnection")
    {
        this.Configuration.ProxyCreationEnabled = false;
    }
}

2) затем в контроллере учетной записи обновите информацию о пользователе следующим образом:

UserDbContext userDbContext = new UserDbContext();
userDbContext.Entry(user).State = System.Data.Entity.EntityState.Modified;
await userDbContext.SaveChangesAsync();

здесь user - это ваше обновление сущность.

надеюсь, что это поможет вам.

отлично!!!

IdentityResult result = await UserManager.UpdateAsync(user);

на основе вашего вопроса, а также отметил в комментарии.

может кто-то направить меня о том, как обновить сведения о пользователе в базе данных?

Да, код верен для обновления любого ApplicationUser в базу данных.

IdentityResult result = await UserManager.UpdateAsync(user);

  • Проверьте ограничения всех обязательных значений поля
  • проверка для UserManager создается с помощью ApplicationUser.

UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

это работает для меня. Я использую Identity 2.0, похоже, GetApplicationUser больше нет.

        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (!string.IsNullOrEmpty(form["FirstName"]))
        {
            user.FirstName = form["FirstName"];
        }
        if (!string.IsNullOrEmpty(form["LastName"]))
        {
            user.LastName = form["LastName"];
        }
        IdentityResult result = await UserManager.UpdateAsync(user);

Я использую новый EF & Identity Core и у меня та же проблема, с добавлением, что у меня есть эта ошибка:

экземпляр типа сущности не может быть отслежен, так как другой экземпляр этот тип с тем же ключом уже отслеживается.

С новой моделью DI я добавил контроллер конструктора контекст в БД.

Я попытался увидеть, что такое конфликт с _conext.ChangeTracker.Entries() и добавить AsNoTracking() на мои звонки без успех.

мне нужно только изменить состояние моего объекта (в этом случае идентичность)

_context.Entry(user).State = EntityState.Modified;
var result = await _userManager.UpdateAsync(user);

и работал без создания другого магазина или объекта и отображения.

Я надеюсь, что кто-то еще пригодятся мои два цента.

добавьте следующий код в свой стартап.Автор.cs-файл под статическим конструктором:

        UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

строка настройки UserManagerFactory кода-это то, что вы используете для связывания пользовательского DataContext с UserManager. Как только вы это сделаете, то вы можете получить экземпляр класса UserManager в ApiController и класса UserManager.Метод UpdateAsync (user) будет работать, потому что он использует ваш DataContext для сохранения дополнительных свойств, добавленных в пользовательское приложение пользователь.

Comments

    Ничего не найдено.