简体   繁体   中英

Get the Role list of a logged in user

With my code I can only get the first role from the list. How would I do to show all the roles that the logged in user has, using razor

@using System.Security.Claims

@{
    var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
    var roleOfUser = claimsIdentity != null ? claimsIdentity.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role).Value : "User";
}

<div class="col-md-9 text-center " id="logoutForm">
    @Html.DisplayName("Profile " + roleOfUser)
</div>

Change the Linq query to return an IEnumerable and use a @foreach loop to display the values

@using System.Security.Claims

@{
 var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
 var rolesOfUser = claimsIdentity != null ? claimsIdentity.Claims.Where(x => 
 x.Type == ClaimTypes.Role).Select(c=>c.Value) : "User";
}

<div class="col-md-9 text-center " id="logoutForm">

  @foreach(var item in rolesOfUser)
  {
    Html.DisplayName("Profile " + item)
  }
</div>

I've just replaced SingleOrDefault with ToList and joined the strings together:

@using System.Security.Claims

@{
    var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
    var roleOfUser = claimsIdentity != null ? string.Join(", ", claimsIdentity.Claims.Where(x => x.Type == ClaimTypes.Role).Select(x=>x.Value).ToList()): "User";
}

  <div class="col-md-9 text-center " id="logoutForm">
     @Html.DisplayName("Profile " + roleOfUser)
  </div>

You were really close but you were using SingleOrDefault which returns one entry or null in this case. ToList returns all the results to that query. string.Join joins all the strings together using , as a separator.

You're just getting the first role of the user and displaying it. If you'd like to get all of them, use one of the methods that produce an IEnumerable instead.

For example, you could do something like this:

@using System.Security.Claims
@{
    Claim[] rolesOfUser = null;
    var claimsIdentity = User.Identity as System.Security.Claims.ClaimsIdentity;
    if (claimsIdentity != null)
    {
        rolesOfUser = claimsIdentity.Claims.Where(x => x.Type ==ClaimTypes.Role).ToArray();
    }
}

@if (rolesOfUser != null && rolesOfUser.Any())
{
    <div class="col-md-9 text-center " id="logoutForm">
        <ul class="list-group user-roles">
            @foreach(var role in rolesOfUser){
                <li class="list-group-item">
                    @Html.DisplayName("Profile " + role)
                </li>
            }
        </ul>
    </div>
}
else
{
    <div class="alert alert-danger">
        No roles where found!
    </div>
}

Here you're getting all the claims from the user that has the Role type and showing them in a list.

BEST PRACTICE

While the above solution works, it's not the cleanest way to do this. The best practice will be to create a model on your controller and pass it to the view as its model. That model should only contain the elements you want to display on the view. That way you don't endup mixing the logic to extract the roles with the presentation logic and your view will be cleaner.

UPDATE: See this fiddle for a possible cleaner implementation: https://dotnetfiddle.net/hM7prf

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM