0

My ASP.NET identity UpdateAsync stopped working without any change in my code. I was working on this project with Visual studio 2015 but recently moved to 2017. I also changed from IIS express in visual to Full IIS. Everything works fine except updateAsync when updating user data.

It throws a silent error "Object not set to an instance of an object" when I call the user manager. The confusing part is that the same user manager is used to create a new user, get a collection of users etc. Only updateAsync fails. I just can get my head around what may be causing this behavior:

public class AppUser : IdentityUser<int, AppUserLogin, AppUserRole, AppUserClaim>, IUser<int>
{
    [Index("EmployeeNumberIndex",IsUnique = true)]
    public int EmployeeNumber { set; get; }

    public virtual string FirstName { set; get; }

    public virtual string MiddleName { set; get; }

    public virtual string LastName { set; get; }

    public virtual string Sex { set; get; }

    public virtual DateTime DateOfBirth { set; get; }

    public virtual int UserType { set; get; }  // 0 for normall memebers and 1 for admin

    public virtual DateTime DateJoined { set; get; }

    public virtual string ProfileImage { set; get; }

    public virtual string DepartmentName { set; get; }

    public virtual string Jobdescription { set; get; }

    public virtual string Password { set; get; }

    public virtual int PasswordChanged { set; get; }

    // guarantors details
    public virtual string Guarantor1FullName { set; get; }
    public virtual string Guarantor1Address { set; get; }
    public virtual string Guarantor1PhoneNumber { set; get; }
    public virtual string Guarantor1Email { set; get; }

    public virtual string Guarantor2FullName { set; get; }
    public virtual string Guarantor2Address { set; get; }
    public virtual string Guarantor2PhoneNumber { set; get; }
    public virtual string Guarantor2Email { set; get; }




    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(AppUserManager manager, string authenticationType)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
        // Add custom user claims here
        return userIdentity;
    }

}

This is the method that calls the updateAsync

public async Task<IdentityResult> UpdateUser(AppUser user)
    {
        AppUser usr;
        usr = await UserManager().FindByIdAsync(user.Id);
        if (usr == null)
        {
            return new IdentityResult("Member does not exist!");
        }

        usr.EmployeeNumber = user.EmployeeNumber;
        usr.FirstName = user.FirstName;
        usr.LastName = user.LastName;
        usr.MiddleName = user.MiddleName;
        usr.PhoneNumber = user.PhoneNumber;
        usr.Email = user.Email;
        usr.UserName = user.Email;
        usr.ProfileImage = user.ProfileImage;
        usr.Jobdescription = user.Jobdescription;

        if (user.DateJoined != DateTime.MinValue)  
        {
            usr.DateJoined = user.DateJoined;
        }

        if (user.DateOfBirth != DateTime.MinValue)
        {
            usr.DateOfBirth = user.DateOfBirth;
        }

        if (user.Sex != null)
        {
            usr.Sex = user.Sex;
        }

        usr.Guarantor1Address = user.Guarantor1Address;
        usr.Guarantor1Email = user.Guarantor1Email;
        usr.Guarantor1FullName = user.Guarantor1FullName;
        usr.Guarantor1PhoneNumber = user.Guarantor2PhoneNumber;
        usr.Guarantor2Address = user.Guarantor2Address;
        usr.Guarantor2Email = user.Guarantor2Email;
        usr.Guarantor2FullName = user.Guarantor2FullName;
        usr.Guarantor2PhoneNumber = user.Guarantor2PhoneNumber;


        try
        {
            return await UserManager().UpdateAsync(usr);

        }catch(Exception ex)
        {
            throw ex;
        }


    }

This the line that fails without inner exception:

return await UserManager().UpdateAsync(usr);

This is the UserManager

    public AppUserManager UserManager()
    {
       return HttpContext.Current.GetOwinContext().GetUserManager<AppUserManager>();

    }

While this is the appUserManager:

public class AppUserManager : UserManager<AppUser, int>
{
    public AppUserManager(IUserStore<AppUser, int> store)
        : base(store)
    {

    }

    public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {

        AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
        AppUserManager manager = new AppUserManager(new AppUserStore(db));


        // add password validations
        manager.PasswordValidator = new CustomPasswordValidator()
        {
            RequiredLength = 8,
            RequireNonLetterOrDigit = true,
            RequireUppercase = true,
            RequireDigit = true,
            RequireLowercase=true

        };


        manager.UserValidator = new UserValidator<AppUser, int>(manager)
        {
            RequireUniqueEmail = true,

        };

        var provider = new DpapiDataProtectionProvider("http://coopone.local");
        manager.UserTokenProvider =
            new DataProtectorTokenProvider<AppUser, int>(provider.Create("Email Reset"));
        ;

        return manager;
    }
}
  • as you said you deployed to IIS, maybe something is fishy with your runtime environment, check this out https://stackoverflow.com/questions/18383923/why-is-httpcontext-current-null-after-await – Tewr Jul 10 '17 at 22:59
  • Thanks, @Tewr. The link was helpful. HttpRuntime was not pointing to any targetFramework thus the `async` and `await` was having an unexpected behavior. This got missing after the upgrade to Visual studio 2017. I updated `` to `` and it working now. – Trust Okoroego Jul 11 '17 at 04:43

0 Answers0