1

I used this code for admin panel to changed password of customer by manager,I did not get any Error. but password not changed, i got my coed from this

 [HttpPost]
    [ValidateAntiForgeryToken]
    public virtual  ActionResult ChangeUserPassword(SetPasswordViewModel model,string userId)
    {
        if (ModelState.IsValid)
        {
            //var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
            ApplicationUser appUser = db.Users.Find(userId);
            var result =  UserManager.ChangePasswordAsync(appUser, model.NewPassword);
           if (result.IsCompleted)
            {
                var user =  UserManager.FindById(User.Identity.GetUserId());
                //var user = db.Users.Find(userId);
                if (user != null)
                {
                    //await SignInManager<,>.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                }
                return RedirectToAction("Index", new { Message = ManageController.ManageMessageId.SetPasswordSuccess });
            }
            // AddErrors(result);
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

}

and in controller for change use this

 public async Task<IdentityResult> ChangePasswordAsync(ApplicationUser Appuser, string newPassword)
    {
        var store = this.Store as Microsoft.AspNet.Identity.IUserPasswordStore<ApplicationUser,string>;
        if (store == null)
        {
            var errors = new string[]
            {
            "Current UserStore doesn't implement IUserPasswordStore"
            };
            return IdentityResult.Failed(errors);
            // return Task.FromResult(new IdentityResult(errors) { Succeeded = false });

        }

        var newPasswordHash = this.PasswordHasher.HashPassword(newPassword);

        await store.SetPasswordHashAsync(Appuser, newPasswordHash);
        await store.UpdateAsync(Appuser);

        //return await Task.FromResult<IdentityResult>(IdentityResult.Success);
        return IdentityResult.Success;
    }
}

whats my mistake?

after update answer i use this method instead

 [HttpPost]
    public async Task<IdentityResult> ChangePasswordAsync(ApplicationUser appuserId, string newPassword)
    {
        ApplicationDbContext db = new ApplicationDbContext();
        //var userr =await db.Users.FirstOrDefaultAsync(x => x.Id == appuserId.Id);

        var newPasswordHash = this.PasswordHasher.HashPassword(newPassword);

        db.Entry(Users).State = EntityState.Modified;
        if (appuserId != null) appuserId.PasswordHash = newPasswordHash;
        db.SaveChanges();
        return IdentityResult.Success;
    }

but had the same problem again

in IdentityModels.cs i had

 public DbSet<CommonAction> CommonActions { get; set; }
    public DbSet<PublicContent> PublicContents { get; set; }
    public DbSet<MainSubject> MainSubjects { get; set; }
    public DbSet<EducationLevel> EducationLevels { get; set; }
    public DbSet<TimePeriod> TimePeriods { get; set; }
    public DbSet<HelpType> HelpTypes { get; set; }
    public DbSet<FinancialSupport> FinancialSupports { get; set; }
    public DbSet<LinksStatistic> LinksStatistics { get; set; }
    public DbSet<SlideOfCommonAction> SlideOfCommonActions { get; set; }

in normal model IdentityModel User is not register as DbSet ()

Community
  • 1
  • 1
sunny
  • 2,670
  • 5
  • 24
  • 39
  • What is the object `Users` in the line `db.Entry(Users).State`? – smoksnes Aug 05 '16 at 10:48
  • its the same as _ApplicationUser_ it's mean if i add this `public DbSet Users { get; set; }`.i got this error `Multiple object sets per type are not supported. The object sets 'Users' and 'Users' can both contain instances of type 'NGO.Models.ApplicationUser'.` – sunny Aug 05 '16 at 16:22

1 Answers1

1

You're not awaiting ChangePasswordAsync, you're just checking if it's completed or not. Which may result in the View being returned before the password has been changed.

Then you should try to use async/await all the way, if possible. That means that your action should be async as well.

 [HttpPost]
    [ValidateAntiForgeryToken]
    public virtual async Task<ActionResult> ChangeUserPassword(SetPasswordViewModel model,string userId)
    {
        if (ModelState.IsValid)
        {
            //var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
            ApplicationUser appUser = db.Users.Find(userId);

            // await the result.
            var result = await UserManager.ChangePasswordAsync(appUser, model.NewPassword);
           if (result.Succeeded) // Or whatever you're expecting.
            {
                var user =  UserManager.FindById(User.Identity.GetUserId());
                //var user = db.Users.Find(userId);
                if (user != null)
                {
                    //await SignInManager<,>.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                }
                return RedirectToAction("Index", new { Message = ManageController.ManageMessageId.SetPasswordSuccess });
            }
            // AddErrors(result);
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

}

Update after comments:

The entity type DbSet`1 is not part of the model for the current context

db.Entry(Users).State = EntityState.Modified;

This is when EF cannot connect your model to an entity in the context. Without seeing the code, it's hard to say exactly why. But it could be that your're missing a DbSet in your context.

Have you configured your UserManager correctly? Does the other UserManager actions work?

Try debugging and see where it crashes.

smoksnes
  • 10,509
  • 4
  • 49
  • 74