ArgumentNullException: Value cannot be null after setting up authentication with Identity

AE 1 Reputation point
2022-05-24T22:33:27.933+00:00

I am getting this bizarre error without any kind of reference to a line in the code after setting up authentication using Identity. The strange thing is that everything was working fine until I deleted every record in my ApplicationUser table. What is the problem ?!

My Implementation of IUserStore and IPasswordStore

public class UserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
{

    // IMPLEMENTING IUserStore
    //////////////////////////////////
    ///

    public async Task<IdentityResult> CreateAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
            //db connection info
        };

        cancellationToken.ThrowIfCancellationRequested();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var addUserCommand = connection.CreateCommand();
            addUserCommand.CommandText = @"
            INSERT INTO ApplicationUser(userName, normalizedUserName, passwordHash)
            VALUES (@userName, @normalizedUserName, @passwordHash)";

            addUserCommand.Parameters.AddWithValue("@userName", user.UserName);
            addUserCommand.Parameters.AddWithValue("@normalizedUserName", user.NormalizedUserName);
            addUserCommand.Parameters.AddWithValue("@passwordHash", user.PasswordHash);

            await addUserCommand.ExecuteNonQueryAsync();
            var selectLastIdCommand = connection.CreateCommand();
            string lastInsertedId = "";
            selectLastIdCommand.CommandText = @"SELECT LAST_INSERT_ID();";


            using var reader = await selectLastIdCommand.ExecuteReaderAsync();
            while (reader.Read())
            {
                user.Id = Int32.Parse(reader[0].ToString());
            }

            reader.Close();

        }

        return IdentityResult.Success;
    }


    public async Task<IdentityResult> DeleteAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
            //db connection info
        };

        cancellationToken.ThrowIfCancellationRequested();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var deleteUserCommand = connection.CreateCommand();
            deleteUserCommand.CommandText = @"
            DELETE FROM ApplicationUser
            WHERE ApplicationUser.id = @id;";
            deleteUserCommand.Parameters.AddWithValue("@id", user.Id);

            deleteUserCommand.ExecuteNonQueryAsync();


        }
        return IdentityResult.Success;
    }

    public async Task<ApplicationUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
            //db connection info
        };

        cancellationToken.ThrowIfCancellationRequested();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var findByIdCommand = connection.CreateCommand();
            findByIdCommand.CommandText = @"
            SELECT * FROM ApplicationUser
            WHERE ApplicationUser.id = @id;";
            findByIdCommand.Parameters.AddWithValue("@id", Int32.Parse(userId));



            using var reader = await findByIdCommand.ExecuteReaderAsync();
            ApplicationUser user = new ApplicationUser();
            while (reader.Read())
            {
                user.Id = Int32.Parse(reader[0].ToString());
                user.UserName = reader[1].ToString();
                user.NormalizedUserName = reader[2].ToString();
                user.PasswordHash = reader[3].ToString();
            }

            reader.Close();

            return user;

        }
    }

    public async Task<ApplicationUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
            //db connection info
        };

        ApplicationUser user = new ApplicationUser();

        cancellationToken.ThrowIfCancellationRequested();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var findByNameCommand = connection.CreateCommand();
            findByNameCommand.CommandText = @"
            SELECT * FROM ApplicationUser
            WHERE normalizedUserName = @normalizedUserName;";
            findByNameCommand.Parameters.AddWithValue("@normalizedUserName", normalizedUserName);

            using var reader = await findByNameCommand.ExecuteReaderAsync();

            while (reader.Read())
            {
                user.Id = Int32.Parse(reader[0].ToString());
                user.UserName = reader[1].ToString();
                user.NormalizedUserName = reader[2].ToString();
                user.PasswordHash = reader[3].ToString();
            }

            reader.Close();
        }

        return user;
    }



    public Task<string> GetNormalizedUserNameAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        return Task.FromResult(user.NormalizedUserName);
    }

    public Task<string> GetUserIdAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        return Task.FromResult(user.Id.ToString());
    }

    public Task<string> GetUserNameAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        return Task.FromResult(user.UserName);
    }

    public Task SetNormalizedUserNameAsync(ApplicationUser user, string normalizedName, CancellationToken cancellationToken)
    {
        user.NormalizedUserName = normalizedName;
        return Task.FromResult(0);
    }

    public Task SetUserNameAsync(ApplicationUser user, string userName, CancellationToken cancellationToken)
    {
        user.UserName = userName;
        return Task.FromResult(0);
    }

    public async Task<IdentityResult> UpdateAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        return IdentityResult.Success;
    }

    public void Dispose()
    {
        // Nothing to dispose.
    }

    // IMPLEMENTING IUserPasswordStore
    //////////////////////////////////
    ///


    public Task SetPasswordHashAsync(ApplicationUser user, string passwordHash, CancellationToken cancellationToken)
    {
        user.PasswordHash = passwordHash;
        return Task.FromResult(0);
    }

    public Task<string> GetPasswordHashAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        return Task.FromResult(user.PasswordHash);
    }

    public Task<bool> HasPasswordAsync(ApplicationUser user, CancellationToken cancellationToken)
    {
        return Task.FromResult(user.PasswordHash != null);
    }

}

My implementation of IRoleStore

public class RoleStore : IRoleStore<ApplicationRole>
{


    public async Task<IdentityResult> CreateAsync(ApplicationRole role, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
            //db connection info
        };

        cancellationToken.ThrowIfCancellationRequested();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var addRoleCommand = connection.CreateCommand();
            addRoleCommand.CommandText = @"
            INSERT INTO ApplicationRole(id,name,normalizedName)
            VALUES(@id, @name, @normalizedName);";
            addRoleCommand.Parameters.AddWithValue("@id", role.Id);
            addRoleCommand.Parameters.AddWithValue("@name", role.Name);
            addRoleCommand.Parameters.AddWithValue("@normalizedName", role.NormalizedName);
            await addRoleCommand.ExecuteNonQueryAsync();
        }
        return IdentityResult.Success;
    }

    public async Task<IdentityResult> UpdateAsync(ApplicationRole role, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }

    public async Task<IdentityResult> DeleteAsync(ApplicationRole role, CancellationToken cancellationToken)
    {
        throw new NotImplementedException();
    }

    public Task<string> GetRoleIdAsync(ApplicationRole role, CancellationToken cancellationToken)
    {
        return Task.FromResult(role.Id.ToString());
    }

    public Task<string> GetRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken)
    {
        return Task.FromResult(role.Name);
    }

    public Task SetRoleNameAsync(ApplicationRole role, string roleName, CancellationToken cancellationToken)
    {
        role.Name = roleName;
        return Task.FromResult(0);
    }

    public Task<string> GetNormalizedRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken)
    {
        return Task.FromResult(role.NormalizedName);
    }

    public Task SetNormalizedRoleNameAsync(ApplicationRole role, string normalizedName, CancellationToken cancellationToken)
    {
        role.NormalizedName = normalizedName;
        return Task.FromResult(0);
    }

    public async Task<ApplicationRole> FindByIdAsync(string roleId, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
           //db connection info
        };

        cancellationToken.ThrowIfCancellationRequested();
        ApplicationRole role = new ApplicationRole();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var findByIdCommand = connection.CreateCommand();
            findByIdCommand.CommandText = @"
            SELECT * FROM ApplicationUser
            WHERE id = @id";
            findByIdCommand.Parameters.AddWithValue("@id", roleId);

            using var reader = await findByIdCommand.ExecuteReaderAsync();

            while (reader.Read())
            {
                role.Id = Int32.Parse(reader[0].ToString());
                role.Name = reader[1].ToString();
                role.NormalizedName = reader[2].ToString();

            }

            reader.Close();
        }


        return role;
    }

    public async Task<ApplicationRole> FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken)
    {
        var builder = new MySqlConnectionStringBuilder
        {
            //db connection info
        };

        cancellationToken.ThrowIfCancellationRequested();
        ApplicationRole role = new ApplicationRole();

        using (var connection = new MySqlConnection(builder.ConnectionString))
        {
            await connection.OpenAsync(cancellationToken);
            var findByNameCommand = connection.CreateCommand();
            findByNameCommand.CommandText = @"
            SELECT * FROM ApplicationUser
            WHERE normalizedName = @name";
            findByNameCommand.Parameters.AddWithValue("@normalizedName", normalizedRoleName);

            using var reader = await findByNameCommand.ExecuteReaderAsync();

            while (reader.Read())
            {
                role.Id = Int32.Parse(reader[0].ToString());
                role.Name = reader[1].ToString();
                role.NormalizedName = reader[2].ToString();

            }

            reader.Close();
        }


        return role;
    }

    public void Dispose()
    {
        // Nothing to dispose.
    }
}

ApplicationUser

public class ApplicationUser
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public string NormalizedUserName { get; set; }
    public string PasswordHash { get; set; }

}

ApplicationRole

public class ApplicationRole
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string NormalizedName { get; set; }
}

Register RazorPage

This page would be the first thing the user requests.

 public class RegisterModel : PageModel
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly ILogger _logger;
    [BindProperty]
    public AuthenticationInputModel model { get; set; }

    public RegisterModel(UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        ILogger<RegisterModel> logger)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _logger = logger;
    }

    public void onGet()
    {
        model = new AuthenticationInputModel();
    }

    public async Task<IActionResult> OnPostRegister(AuthenticationInputModel model)
    {

        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.UserName };
            var result = await _userManager.CreateAsync(user, model.Password);

            if (result.Succeeded)
            {
                _logger.LogInformation("User created a new account with password.");
                await _signInManager.SignInAsync(user, isPersistent: false);


                return RedirectToPage("/Index");
            }

        }

        return Page();

    }
}
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,187 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,275 questions
{count} votes