Identity 2.1, асинхронное программирование и обновление дополнительных пользовательских данных

Я понимаю, что такое асинхронное программирование, но мне трудно реализовать его в моем коде. Identity 2.1 генерирует методы CRUD, и я хочу добавить к нему код. Как я могу сохранить обновление LINQ? Мне нужно использовать ожидание? Таблица AspNetUsers обновляется нормально, но не моя таблица UserProfiles:

// POST: /Users/Edit/5    [Bind(Include = "FirstName,LastName,Email,Id,Address,City,State,PostalCode")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit(EditUserViewModel editUser, params string[] selectedRole)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindByIdAsync(editUser.Id);
            if (user == null)
            {
                return HttpNotFound();
            }

            user.UserName = editUser.Email;
            user.Email = editUser.Email;
            user.Address = editUser.Address;
            user.City = editUser.City;
            user.State = editUser.State;
            user.PostalCode = editUser.PostalCode;

            var userRoles = await UserManager.GetRolesAsync(user.Id);

            selectedRole = selectedRole ?? new string[] { };

            var result = await UserManager.AddToRolesAsync(user.Id, selectedRole.Except(userRoles).ToArray<string>());



            if (!result.Succeeded)
            {
                ModelState.AddModelError("", result.Errors.First());
                return View();
            }
            result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRole).ToArray<string>());

            if (!result.Succeeded)
            {
                ModelState.AddModelError("", result.Errors.First());
                return View();
            }
            //Update Firstname/Lastname
            var dbEntry = db.UserProfiles.Single(x => x.UserId == editUser.Id);
            dbEntry.FirstName = editUser.FirstName;
            dbEntry.LastName = editUser.LastName;
            db.SaveChanges();


            return RedirectToAction("Index");
        }
        ModelState.AddModelError("", "Something failed.");
        return View();
    }

Поскольку мой пост был приостановлен, позвольте мне объяснить свой вопрос более подробно. Вар dbEntry не обновляется в db.SaveChanges (). Когда я просматриваю код, editUser.FirstName и editUser.LastName имеют значение.

У var dbEntry есть запись, которую нужно обновить. Опять же, db.SaveChanges () не сохраняет.

Я думаю, что происходит что-то с асинхронным программированием. Поскольку метод является общедоступным async Task Edit ()

вместо того:

общедоступный ActionResult Edit (). Обновление будет работать с общедоступным ActionResult Edit ().

Поскольку я не использую асинхронное программирование (которое я изучаю), как мне реализовать ожидание в этом методе, чтобы var dbEntry обновлялся?


person JoshYates1980    schedule 19.03.2015    source источник
comment
Так какая у вас проблема с показанным кодом?   -  person Servy    schedule 19.03.2015
comment
var dbEntry никогда не сохраняет.   -  person JoshYates1980    schedule 19.03.2015
comment
Вы уверены, что вызывается SaveChanges? Вы зашли в это с отладчиком?   -  person Erik Funkenbusch    schedule 19.03.2015
comment
Да, я прошел через код, и он не ломается, он просто продолжает шаг за шагом.   -  person JoshYates1980    schedule 19.03.2015


Ответы (2)


Асинхронный аспект не должен быть проблемой. ApplicationDbContext вашего UserManager настроен из коробки с AutoDetectChangesEnabled == true. Скорее всего, ваш второй DbContext - нет. Включите его, если хотите, или явно установите db.Entry(dbEntry).State = EntityState.Modified перед вызовом Save.

person Oskar Lindberg    schedule 30.03.2015
comment
Попался! Спасибо, Оскар! - person JoshYates1980; 30.03.2015

Что ж, это как бы вообще обходит стороной вопрос, но почему вы используете отдельный объект для отслеживания данных профиля? Одна из основных причин, по которой существует Identity, состоит в том, чтобы предоставить более расширяемую систему управления пользователями, что означает, что вам не нужно пытаться использовать функциональные возможности, как раньше, с членством в ASP.NET.

public class ApplicationUser : IdentityUser
{
    // everything else already here

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

Затем просто обновите его вместе с экземпляром пользователя, который вы уже обновляете:

user.UserName = editUser.Email;
user.Email = editUser.Email;
user.Address = editUser.Address;
user.City = editUser.City;
user.State = editUser.State;
user.PostalCode = editUser.PostalCode;
// add these
user.FirstName = editUser.FirstName;
user.LastName = editUser.LastName;

Что еще более сбивает с толку, так это то, что ApplicationUser уже был расширен таким образом, потому что Address, City, State и PostalCode не указаны в IdentityUser. Тогда я не понимаю, почему вы начали обрабатывать информацию об имени и фамилии по-другому.

person Chris Pratt    schedule 19.03.2015
comment
Это не мой призыв. Я унаследовал базу данных, а таблица UserProfile содержит около 40 столбцов. - person JoshYates1980; 19.03.2015
comment
Вы можете провести рефакторинг. Тот факт, что вы унаследовали плохой код, не может служить оправданием для продолжения его использования. - person Chris Pratt; 19.03.2015
comment
Я согласен, но это не отвечает на вопрос, почему обновление никогда не выполняется. - person JoshYates1980; 19.03.2015
comment
@ChrisPratt, некоторые люди работают над миром, который они не могут изменить. Они должны адаптироваться к этому миру. Может быть, потому, что эту базу данных уже использует множество приложений. Может быть, потому, что вы взаимодействуете с близким продуктом. ASP.NET Identity 2 очень хорош для того, что делает, и позволяет всем остальным высохнуть. Существует чрезмерная одержимость хранением вещей, и взаимодействие между ними было полностью исключено. - person Paulo Morgado; 19.03.2015