asp.net-core-webapiasp.net-core-identityuser-rolesasp.net-core-8

Saving custom roles in AspNetUserRoles Identity table from ASP.NET Core 8 Web API


I am trying to develop a backend ASP.NET Core 8 Web API for an Angular and .NET Core based web application. I have created the Identity tables in my SQL Server database using code first migration.

The AspNetRoles table is being populated during the initial migration with the roles "Photographer", "Painter", "Musician". From the front end I am sending the following data to be saved in database for user registration process:

    Email
    FullName
    Password
    SubscriptionType
    Role

The typical POST request for user registration process is like this:

{
  "email": "user1@gmail.com",
  "fullName": "PGC PC",
  "password": "Passw0rd!",
  "confirmPassword": "Passw0rd!",
  "subscriptionType": 0,
  "role":"Photographer"
}

I am able to save the first 4 fields in my AspNetUsers table just fine. What I want to do alongside this is to save the role data in AspNetUserRoles table with the userID. I am unable to do this. My knowledge of ASP.NET Core Identity is not very profound which is why I am struggling.

I have created a RegisterViewModel class as follows:

public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    public string Email { get; set; } = string.Empty;

    [Required]
    public string FullName { get; set; } = string.Empty;

    [Required]
    public string Password { get; set; } = string.Empty;

    [Required]
    public string ConfirmPassword { get; set; } = string.Empty;

    [Required]
    public string SubscriptionType { get; set; } = string.Empty;

    [Required]
    public string Role { get; set; } = string.Empty;
}

My registration method in auth Web API controller file is as follows:

    [HttpPost("register")]
public async Task<ActionResult<string>> Register(RegisterViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    AppUser user = new AppUser
    {
        Email = viewModel.Email,
        FullName = viewModel.FullName,
        SubscriptionType = viewModel.SubscriptionType,
        UserName = viewModel.Email

    };

    IdentityResult result = await _userManager.CreateAsync(user, viewModel.Password);
    if(result.Succeeded)
    {
        IdentityResult roleResult = await _userManager.AddToRoleAsync(user, viewModel.Role);
        if(roleResult.Succeeded)
        {
            return Ok(new AuthResponseViewModel
            {
                Result = true,
                Message = "Accout created and role saved to database!"
            });
        }
        else
        {
            return Ok(new AuthResponseViewModel
            {
                Result = true,
                Message = "Account created but problem saving role to database!"
            }); 
        }
    }
    else
    {
        return BadRequest(result.Errors);
    }
}

where AppUser is defined as:

public class AppUser : IdentityUser
{
    public string FullName { get; set; } = string.Empty;
    public string SubscriptionType { get; set; }=string.Empty;
}

and AuthResponseViewModel class is:

public class AuthResponseViewModel
{
    public string Token { get; set; } = string.Empty;
    public bool Result { get; set; }
    public string Message { get; set; } = string.Empty;
}

Can you please tell me what code to add/edit where and how, so that I can save the role data ie Photographer, Painter, Musician etc. in the AspNetUserRoles table along with the userID value? Any kind of documentation, code samples or snippets would be welcome. I have been trying to search a similar scenario on the internet forums but to no avail. Any kind of assistance would be massively appreciated.

Thanks in anticipation!


Solution

  • If the roles already exists in AspNetRoles, enter image description here

    You can call the _userManager.AddToRoleAsync() method in the register method to add the user to the specified role after the user is successfully created. For example:

    IdentityResult createResult = await _userManager.CreateAsync(user, viewModel.Password);
    if (!createResult.Succeeded)
    {
        return BadRequest(createResult.Errors);
    }
    
    
    IdentityResult roleResult = await _userManager.AddToRoleAsync(user, viewModel.Role);
    if (!roleResult.Succeeded)
    {
        return BadRequest(roleResult.Errors);
    }
    

    After calling the method in my AspNetUserRoles

    enter image description here

    If the role does not exist in the AspNetRoles table, you can create it through the SeedRolesAsync method:

    public static async Task SeedRolesAsync(RoleManager<IdentityRole> roleManager)
    {
        string[] roleNames = { "Photographer", "Painter", "Musician" };
    
        foreach (var roleName in roleNames)
        {
            if (!await roleManager.RoleExistsAsync(roleName))
            {
                await roleManager.CreateAsync(new IdentityRole(roleName));
            }
        }
    }