2

I am doing custom asp.net identity and not using asp.net inbuilt tables.I have successfully created user with implementing custom CreateAsync

Now i want to update user with new encrypted password and so i am not getting how to provide custom implementation of UpdateAsync method.

This is my table:

User : Id,Name,EmailId,Password,Statistics,Salary

Model:

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; }
}

My custom class which implements 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
    }
}

Controller:

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);
    }        
}
David Pine
  • 23,787
  • 10
  • 79
  • 107
I Love Stackoverflow
  • 6,738
  • 20
  • 97
  • 216
  • 2
    Using `Task.Factory.StartNew` to push the method onto a background thread seems like a bad idea. Either mark the methods as `async` and use `await _dbContext.SaveChangesAsync();`, or make the methods synchronous and return `Task.FromResult(true);` at the end. – Richard Deeming Sep 01 '16 at 18:24
  • @richard deeming thank you so much for very nice suggestion.i really appreciate it.sometimes I am facing problem like when I debug this code then call never return back.is it because of this task.factory.new?? – I Love Stackoverflow Sep 01 '16 at 18:34
  • 1
    Possibly. And even if it's not, removing the `Task.Factory.StartNew` might make it easier to see the error. – Richard Deeming Sep 01 '16 at 18:40
  • 1
    You've also got a variable naming conflict in `CreateAsync`: the `user` variable defined within the `Task.Factory.StartNew` delegate hides the `user` parameter. But I suspect that's just a typo in your question, as you then use an undefined variable called `dbUser`. :) – Richard Deeming Sep 01 '16 at 18:42
  • @richard deeming yeah that is just a typing mistake.apart from this can you suggest me something about implementation of updateasync please?? – I Love Stackoverflow Sep 01 '16 at 18:48
  • 1
    I'd avoid touching the password in the `UpdateAsync` method - AFAIK, that's only for updating *other* properties. The `SetPasswordHashAsync` method is used to update the password. – Richard Deeming Sep 01 '16 at 18:57
  • @Richard Deeming I am updating user and during this update user will enter his new password and then simply I will overwwrite this new password with the old password.so how do I call this method setpasswordhash for encrypting my password for update process.can you please guide me a little – I Love Stackoverflow Sep 01 '16 at 19:09
  • 2
    Something like this: http://stackoverflow.com/a/37866098/124386 – Richard Deeming Sep 01 '16 at 19:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122533/discussion-between-learning-and-richard-deeming). – I Love Stackoverflow Sep 02 '16 at 16:20

2 Answers2

2

Not sure if this is what your looking for...

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

It Will get the specific record and Update the password and then save the record.

Edit

Since the password is not getting encrypted i added code to take that string and leave the model as it is, this extension method will encrypt the value of password, i have not test this but i am sure it will work.

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

Extension methods to encrypt password

Yuri Cardoso
  • 113
  • 1
  • 13
Sarel Louw
  • 378
  • 2
  • 11
0

Sometime back, I created a complete wrapper over .NET Identity and code can be found here. It might be helpful for you. You can also find nuget here. I also explained the library in a blog here.

Rahul Garg
  • 4,069
  • 1
  • 34
  • 31