1

I am working on a webapp in razor pages using .net core 2. I implemented the standard individual accounts and I am able to work with the data.

However, I'd like to extend my dashboard by displaying the users with its corresponding role.

I have these tables:

mssql

AspNetUsers
UserId | Email | Password | Etc

AspNetRoles
RoleId | RoleName

AspNetUserRoles
UserId | RoleId

users.cshtml.cs

private readonly ApplicationDbContext _dbContext;

public List<ApplicationUser> users { get; set; }

public UsersModel(ApplicationDbContext dbContext)
{
    _dbContext = dbContext;
}

public async void OnGet()
{
    users = _dbContext.Users.ToList();
}

When I loop use @foreach(var user in @Model.users, I can only (ofcourse) access the columns of the AspNetUsers-table.

I'd like to query over all my users and use user.Role for example.

I am aware of this solution

  var admins = _userManager.GetUsersInRoleAsync("Admin").Result;

But I don't want to repeat myself a couple of times. Everything needs to be dynamic. And I'd like to change this role, since I have to be able to edit it later on.

So, my concrete question is: how can I accomplish the following situation based on my current database structure and code by using LINQ?

My ideal situation

// my .cshtml
<table>
    <tbody>
         @foreach(var user in @Model.users)
         {
             <tr>@user.Name - @user.Role</tr>
         }
    </tbody>
</table>

edit 1 ###

    public class ApplicationUser : IdentityUser
    {
        [NotMapped]
        public virtual ICollection<IdentityRole<string>> Roles { get; set; }
    }

Error:

Unhandled Exception: System.InvalidOperationException: The property 'Roles' is not a navigation property of entity type 'ApplicationUser'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.
M. Douglas
  • 63
  • 7

1 Answers1

1

You can make a query that returns a list of users with roles or modify your current one to Include the roles like this:

users = _dbContext.Users
    .Include(u => u.Roles)
    .ToList();

Now in your Razor code you can do this:

@foreach(var user in @Model.users)
{
    foreach(var role in user.Roles)
    {
        <tr>@user.Name - @role.Name</tr>
    }
}

Note: Your HTML table code needs a little work as it doesn't have any tr or th/td elements

DavidG
  • 113,891
  • 12
  • 217
  • 223
  • It fails on line: ".Include(u => u.Roles)". I am getting an error: "Cannot resolve symbol 'Roles'" – M. Douglas Apr 30 '18 at 16:25
  • Oh yes, It's Identity Core... You may need to add the navigation property to your user class. – DavidG Apr 30 '18 at 16:26
  • I added @page to the .cshtml, the using statement for ApplicationUser to my .cs-file, but it's still not working. – M. Douglas Apr 30 '18 at 16:31
  • No, I mean to your `ApplicationUser` class, add a line something like this: `public virtual ICollection Roles { get; set; }` – DavidG Apr 30 '18 at 16:31
  • I've added `public virtual ICollection Roles { get; set; }`, but it crashes and shows me the error: `Invalid column name 'ApplicationUserId'.` – M. Douglas Apr 30 '18 at 16:34
  • Why did you add `NotMapped` attribute? Remove that. – DavidG Apr 30 '18 at 16:49
  • Otherwise I keep getting the error mentioned earlier, about the invalid column name. `NotMapped` fixed this error but produced another one. – M. Douglas Apr 30 '18 at 16:50
  • Take a look at this https://stackoverflow.com/questions/47767267/ef-core-2-how-to-include-roles-navigation-property-on-identityuser – DavidG Apr 30 '18 at 16:53