question

AE-5032 avatar image
0 Votes"
AE-5032 asked AgaveJoe commented

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

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();

     }
 }

dotnet-csharpdotnet-aspnet-core-generaldotnet-aspnet-core-auth
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Which line of code or which action will show the ArgumentNullException exception?

The strange thing is that everything was working fine until I deleted every record in my ApplicationUser table. What is the problem ?!

Whether this issue happens on the login page, since you deleted all records, when you login, the ApplicationUser table doesn't have any records, so the result is null?

0 Votes 0 ·

The AspNetUsers table contains a SecurityStamp column which is used to invalidate the authentication token. If you deleted the user accounts but did not delete the authentication cookie then I suppose that could cause errors as well.

Lastly, the URL that caused the null expectation is in the browser's address bar. What URL causes the exception?

0 Votes 0 ·

0 Answers