Как предоставить пользовательскую реализацию метода UpdateAsync для идентификации asp.net?

Я использую пользовательский идентификатор asp.net и не использую встроенные таблицы asp.net. Я успешно создал пользователя с реализацией пользовательских CreateAsync

Теперь я хочу обновить пользователя с новым зашифрованным паролем, и поэтому я не понимаю, как обеспечить пользовательскую реализацию UpdateAsync method.

Это моя таблица:

Пользователь : Id,Name,EmailId,Password,Statistics,Salary

Модель:

public class UserModel : IUser 
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string EmailId { get; set; }  
    public string Password { get; set; }
    public int Salary { get; set; }
}

Мой собственный класс, реализующий IUserstore:

public class UserStore : IUserStore<UserModel>, IUserPasswordStore<UserModel>
{
    private readonly MyEntities _dbContext;
    private readonly HttpContext _httpContext;

    // How to implement this method for updating only user password
    public Task UpdateAsync(UserModel user)
    {
        throw new NotImplementedException();
    }

    public Task CreateAsync(UserModel user)
    {
        return Task.Factory.StartNew(() =>
            {
                HttpContext.Current = _httpContext ?? HttpContext.Current;
                var user = _dbContext.User.Create();
                user.Name = user.Name;
                user.EmailId = user.EmailId;
                user.EmailAddress = user.Email;
                user.Password = user.Password;
               _dbContext.Users.Add(dbUser);
               _dbContext.SaveChanges();
            });
    }

    public Task SetPasswordHashAsync(UserModel user, string passwordHash)
    {
        return Task.Factory.StartNew(() =>
            {
                HttpContext.Current = _httpContext ?? HttpContext.Current;
                var userObj = GetUserObj(user);
                if (userObj != null)
                {
                    userObj.Password = passwordHash;
                    _dbContext.SaveChanges();
                }
                else
                    user.Password = passwordHash;
            });
    }

    public Task<string> GetPasswordHashAsync(UserModel user)
    { 
        //other code
    }
}

Контроллер:

public class MyController : ParentController
{
    public MyController()
        : this(new UserManager<UserModel>(new UserStore(new MyEntities())))
    {
    }

    public UserManager<UserModel> UserManager { get; private set; }

    [HttpPost]
    public async Task<JsonResult> SaveUser(UserModel userModel)
    {
        IdentityResult result = null;
        if (userModel.Id > 0) //want to update user with new encrypted password
            result = await UserManager.UpdateAsync(user);
        else
            result = await UserManager.CreateAsync(userModel.EmailId, userModel.Password);
    }        
}

person Learning-Overthinker-Confused    schedule 01.09.2016    source источник
comment
Использование Task.Factory.StartNew для передачи метода в фоновый поток кажется плохой идеей. Либо отметьте методы как async и используйте await _dbContext.SaveChangesAsync();, либо сделайте методы синхронными и возвращайте Task.FromResult(true); в конце.   -  person Richard Deeming    schedule 01.09.2016
comment
@richard большое спасибо за очень хорошее предложение. Я очень ценю его. Иногда я сталкиваюсь с проблемой, например, когда я отлаживаю этот код, а затем вызов никогда не возвращается обратно. это из-за этой задачи.factory.new ??   -  person Learning-Overthinker-Confused    schedule 01.09.2016
comment
Возможно. И даже если это не так, удаление Task.Factory.StartNew может упростить просмотр ошибки.   -  person Richard Deeming    schedule 01.09.2016
comment
У вас также есть конфликт имен переменных в CreateAsync: переменная user, определенная в делегате Task.Factory.StartNew, скрывает параметр user. Но я подозреваю, что это просто опечатка в вашем вопросе, так как вы используете неопределенную переменную с именем dbUser. :)   -  person Richard Deeming    schedule 01.09.2016
comment
@richard считает, что да, это просто опечатка. Помимо этого, не могли бы вы предложить мне что-нибудь о реализации updateasync, пожалуйста ??   -  person Learning-Overthinker-Confused    schedule 01.09.2016
comment
Я бы не стал трогать пароль в методе UpdateAsync - насколько я знаю, это только для обновления других свойств. Метод SetPasswordHashAsync используется для обновления пароля.   -  person Richard Deeming    schedule 01.09.2016
comment
@Richard Считаю, что я обновляю пользователя, и во время этого обновления пользователь вводит свой новый пароль, а затем просто перезаписываю этот новый пароль старым паролем. Итак, как мне вызвать этот метод setpasswordhash для шифрования моего пароля для процесса обновления. Не могли бы вы направь меня немного   -  person Learning-Overthinker-Confused    schedule 01.09.2016
comment
Что-то вроде этого: stackoverflow.com/a/37866098/124386   -  person Richard Deeming    schedule 01.09.2016
comment
Давайте продолжим обсуждение в чате.   -  person Learning-Overthinker-Confused    schedule 02.09.2016


Ответы (2)


Не уверен, что это то, что вы ищете...

public Task UpdateAsync(UserModel model)
{
    var user = _dbContext.User.Find(x => x.id == model.id);
    user.Password = model.Password;
    _dbContext.SaveChanges();
    return Task.CompletedTask;
}

Он получит конкретную запись и обновит пароль, а затем сохранит запись.

Изменить

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

 user.Password = model.Password.EncryptPassword(EncryptKey);

Методы расширения для шифрования пароля

person Sarel Louw    schedule 01.09.2016
comment
вы можете сохранить любое значение из вашей модели. - person Sarel Louw; 01.09.2016
comment
Но вот мой вопрос: будет ли пароль зашифрован идентификатором Microsoft и сохранен в базе данных, или мой пароль будет сохранен в виде простого текста?? - person Learning-Overthinker-Confused; 01.09.2016
comment
Это сохранит значение, которое находится внутри модели. - person Sarel Louw; 01.09.2016
comment
в вашем методе сохранения пользователя я бы выполнил проверку идентификатора пользователя, затем выполнил преобразование пароля, а затем отправил эту модель в ваш метод обновления. - person Sarel Louw; 01.09.2016
comment
Да, но мой пароль будет хеширован?? - person Learning-Overthinker-Confused; 01.09.2016
comment
Извините, но мой новый пароль не шифруется - person Learning-Overthinker-Confused; 02.09.2016
comment
@Learning, вы должны создать метод расширения для шифрования пароля. вы можете использовать его внутри кода UpdateAsync. Вы хотите, чтобы я объяснил с кодом? model.Password.ChangePassword(hashsymbol) что-то вроде этого - person Sarel Louw; 03.09.2016

Некоторое время назад я создал полную оболочку для .NET Identity, и код можно найти здесь. Это может быть полезно для вас. Вы также можете найти nuget здесь. Я также объяснил библиотеку в блоге здесь .

person Rahul Garg    schedule 03.07.2017