昨天角色的 CRUD 功能都完成了,接着就是要把角色指派给使用者了,先建立一个 ViewModel CustomUserRoleViewModel
,这是用来呈现角色底下使用者的 ViewModel。
namespace BlazorServer.ViewModels
{
public class CustomUserRoleViewModel
{
public string UserId { get; set; }
public string UserName { get; set; }
public bool IsSelected { get; set; }
}
}
再於IRolesRepository
跟RolesRepository
加上编辑角色内使用者的功能,这里用了多载,第一个相当於 Get 取得画面初始资料,第二个则是 Post 送出修改後的资料。
IRolesRepository.cs
…
Task<List<CustomUserRoleViewModel>> EditUsersInRoleAsync(string RoleId);
Task<ResultViewModel> EditUsersInRoleAsync(List<CustomUserRoleViewModel> model, string RoleId);
RolesRepository.cs
…
public async Task<List<CustomUserRoleViewModel>> EditUsersInRoleAsync(string RoleId)
{
var role = await _roleManager.FindByIdAsync(RoleId);
var model = new List<CustomUserRoleViewModel>();
foreach (var user in _userManager.Users)
{
var userRoleViewModel = new CustomUserRoleViewModel
{
UserId = user.Id,
UserName = user.UserName
};
if (await _userManager.IsInRoleAsync(user, role.Name))
{
userRoleViewModel.IsSelected = true;
}
else
{
userRoleViewModel.IsSelected = false;
}
model.Add(userRoleViewModel);
}
return model;
}
public async Task<ResultViewModel> EditUsersInRoleAsync(List<CustomUserRoleViewModel> model, string RoleId)
{
var role = await _roleManager.FindByIdAsync(RoleId);
foreach (var m in model)
{
var user = await _userManager.FindByIdAsync(m.UserId);
IdentityResult result;
if (m.IsSelected && !(await _userManager.IsInRoleAsync(user, role.Name)))
{
result = await _userManager.AddToRoleAsync(user, role.Name);
}
else if (!m.IsSelected && await _userManager.IsInRoleAsync(user, role.Name))
{
result = await _userManager.RemoveFromRoleAsync(user, role.Name);
}
else
{
continue;
}
if (result.Succeeded)
{
if (model.Count > 0)
{
continue;
}
else
{
return new ResultViewModel
{
Message = RoleId,
IsSuccess = true
};
}
}
else
{
return new ResultViewModel
{
Message = RoleId,
IsSuccess = false
};
}
}
return new ResultViewModel
{
Message = RoleId,
IsSuccess = true
};
}
接着加上画面。
EditUsersInRole.razor.cs
using BlazorServer.Services;
using BlazorServer.Shared;
using BlazorServer.ViewModels;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorServer.Pages.RolesManagement
{
public partial class EditUsersInRole
{
[Inject] protected IRolesRepository RolesRepository { get; set; }
[Inject] protected NavigationManager NavigationManager { get; set; }
[Inject] protected IJSRuntime js { get; set; }
private JsInteropClasses jsClass;
[Parameter]
public string RoleId { get; set; }
public List<CustomUserRoleViewModel> UserRoleViewModel { get; set; } = new List<CustomUserRoleViewModel>();
protected override async Task OnInitializedAsync()
{
await loadData();
jsClass = new(js);
}
private async Task loadData()
{
UserRoleViewModel = (await RolesRepository.EditUsersInRoleAsync(RoleId)).ToList();
}
public async Task HandleValidSubmit()
{
var result = await RolesRepository.EditUsersInRoleAsync(UserRoleViewModel, RoleId);
if (result.IsSuccess)
{
NavigationManager.NavigateTo($"/RolesManagement/EditRole/{RoleId}");
}
else
{
await jsClass.Alert(result.Message);
}
}
public void Cancel()
{
NavigationManager.NavigateTo($"/RolesManagement/EditRole/{RoleId}");
}
}
}
EditUsersInRole.razor
@attribute [Authorize]
<EditForm Model="UserRoleViewModel" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="card">
<div class="card-header">
<h2>从角色新增或移除使用者</h2>
</div>
<div class="card-body">
@foreach (var user in UserRoleViewModel)
{
<div class="form-check m-1">
<label class="form-check-label">
<InputCheckbox @bind-Value="@user.IsSelected"></InputCheckbox>
@user.UserName
</label>
</div>
}
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">更新</button>
<button type="button" class="btn btn-danger" @onclick="@Cancel">取消</button>
</div>
</div>
</EditForm>
EditRole.razor.cs
新增一个方法,通往EditUsersInRole.razor
,可以编辑角色底下使用者。
public void EditUsersInRole()
{
NavigationManager.NavigateTo($"/RolesManagement/EditUsersInRole/{RoleId}");
}
EditRole.razor
加上一个按钮呼叫该方法。
<button type="button" class="btn btn-info" @onclick="EditUsersInRole">新增或移除该角色底下的使用者</button>
启动网页进入编辑角色下使用者页面,可以看到目前只有一个使用者,将Admin
角色指派给这个使用者,如此一来就完成了Admin
跟[email protected]
的指派,不过要测试是否成功的话,需要对页面加入限制,还要新增一个使用者测试。
先将每个 razor component 的@attribute [Authorize]
改成@attribute [Authorize(Roles = "Admin")]
,表示要看到这页面的人必须有 Role Admin
。
再去NavMenu.razor
,於原本的<AuthorizeView>
上方加入下面这段程序,同理要看到通往Roles
连结的人必须有 Role Admin
,再把原本<AuthorizeView>
的Roles
连结删除。
<AuthorizeView Roles="Admin">
<Authorized>
<li class="nav-item px-3">
<NavLink class="nav-link" href="RolesManagement/RolesList" Match="NavLinkMatch.All">
<span class="bi bi-kanban-fill h4 p-2 mb-0" aria-hidden="true"></span> Roles
</NavLink>
</li>
</Authorized>
</AuthorizeView>
最後新增一名使用者,名为[email protected]
,以此使用者登入,会发现左边的Roles
不见了,手动输入网址也会提示没有权限,这就是最基本的角色(Role)授权,如果系统很简单只要用角色划分权限,这样就能满足需求了。
Ref:Add or remove users from role in asp net core
<<: Day 12:145. Binary Tree Postorder Traversal
原始出处:(ISC)² Member Counts in Asia ...
观看Laravel 8.0的官方文件教学,可以看到一个新的东西就是我们这次要介绍的Sail,用起来非...
二元搜寻树(Binary Search Tree)建立的方法 insert: 新增元素进入树中 de...
如标题,这篇想和大家聊聊「重复key」的问题 因为当你用print_r去印出有重复key的阵列时,它...
Goroutine Golang 中多执行绪称为" Goroutine" ,在其...