tokyo0709
tokyo0709

Reputation: 1997

Get User Roles with ASP.net Identity and Web API

I am currently trying to get the given user's list of Roles and am having some trouble fitting this into the context we are using it in. I was able to get a list of all available roles with this API function earlier,

[HttpGet]
[Route("GetRoles")]
public async Task<ApiResponse<List<RoleViewModel>>> GetRoles()
{
    try
    {
        //Get Roles
        var roles = await (from r in _db.AspNetRoles
                     select new RoleViewModel { Id = r.Id, Name = r.Name}).ToListAsync();
        return new ApiResponse<List<RoleViewModel>>{ Success = true, Result =  roles };

    }
    catch(Exception ex)
    {
        return new ApiResponse<List<RoleViewModel>> { Success = false, Message = ex.Message };
    }

}

But can't seem to figure out what I need to throw into this one to get a list of the roles for the user. We went with Entity Frameworks Code First from Existing Database approach and are pulling from those tables. Strangely though there is no AspNetUserRoles table since I guess it is just relating the two tables AspNetUsers and AspNetRoles. Anyway, here is the function in question,

[HttpGet]
[Route("GetUserRoles")]
public async Task<ApiResponse<List<RoleViewModel>>> GetUserRoles(string userName)
{
    try
    {
        var userRoles = await (_db.AspNetUsers.FirstOrDefault(u => u.UserName == userName).AspNetRoles).ToListAsync();
    }
    catch (Exception ex)
    {
        return new ApiResponse<List<RoleViewModel>> { Success = false, Message = ex.Message };
    }
}

The current error I am getting is that AspNetRole does not contain a definition for ToListAsync(). I think the async stuff is throwing me a little. And lastly here is the RoleViewModel for reference,

public class RoleViewModel
{
    public string Id { get; set; }

    [Required]
    [StringLength(256)]
    public string Name { get; set; }
}

And the ApiResponse class,

public class ApiResponse<TResult>
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public TResult Result { get; set; }
}

I feel like there should be a simple fix, but I just can't quite grasp what it is.

Upvotes: 3

Views: 6846

Answers (1)

tokyo0709
tokyo0709

Reputation: 1997

Just found the answer to my problem. The main thing I was missing was utilization of the User Manager which made things so much easier. Then I just had to fit things into the functions I had already defined. Here is the code.

[HttpGet]
[Route("GetUserRoles")]
public async Task<ApiResponse<List<RoleViewModel>>> GetUserRoles(string userName)
{
    try
    {
        // Get the user in question
        var aspUser = (from u in _db.AspNetUsers
                       where u.UserName == userName
                       select u).FirstOrDefaultAsync();

        // Check if the user was found
        if (aspUser == null)
        {
            throw new Exception("User was not found");
        }

        // Get the roles associated with that user
        var userRoles = await UserManager.GetRolesAsync(aspUser.Result.Id.ToString());

        // Setup a RoleViewModel list of roles and iterate through userRoles adding them to the list
        List<RoleViewModel> roleList = new List<RoleViewModel>();
        foreach (var u in userRoles)
        {
            var item = new RoleViewModel { Name = u };
            roleList.Add(item);
        }

        return new ApiResponse<List<RoleViewModel>> { Success = true, Result = roleList };
    }
    catch (Exception ex)
    {
        return new ApiResponse<List<RoleViewModel>> { Success = false, Message = ex.Message };
    }
}

Upvotes: 3

Related Questions