基於Asp.Net Core編制一個項目,需要給用戶添加及刪除角色的功能,於是使用到了Identity中的UserManager。
先后解決了幾個問題,終於實現了設想。
1. 環境條件
Asp.Net Core 1.0.1
Microsoft.AspNetCore.Identity.EntityFrameworkCore 1.0.0
2. 給用戶添加角色(組)使用到UserManager.AddToRolesAsync(),元數據中對AddToRolesAsync的解釋為:
// // 摘要: // Add the specified user to the named roles. // // 參數: // user: // The user to add to the named roles. // // roles: // The name of the roles to add the user to. // // 返回結果: // The System.Threading.Tasks.Task that represents the asynchronous operation, containing // the Microsoft.AspNetCore.Identity.IdentityResult of the operation. [AsyncStateMachine(typeof(UserManager<>.<AddToRolesAsync>d__100))] public virtual Task<IdentityResult> AddToRolesAsync(TUser user, IEnumerable<string> roles);
在我的代碼中對應第一個參數的類型是AppcationUser,第二個參數應該是代表角色(組)的字符串列表;
在controller中該行代碼為:
await _userManager.AddToRolesAsync(user, selectedRoles)
在默認角色表中有兩個關角色名的字段,一個是“Name”,另外一個是“NormalizedName”,如下圖所示:
經過嘗試,AddToRolesAsync()中的第二個參數應該是“NormalizedName”。如果使用“Name”會出現錯誤。
3. 刪除用戶已有角色會使用到UserManager.RemoveFromRoleAsync(),這個方法同樣會使用到AddToRolesAsync()中的兩個參數,使用方法與AddToRolesAsync()相同。
但是,Identity提供的獲取用戶現有角色的方法只有:userManager.GetRolesAsync(user),其中參數“user”為<ApplicationUser>。
這個方法的返回值從元數據中給出的解釋是:role names。經過測試實際為“Name”字段。
// // 摘要: // Gets a list of role names the specified user belongs to. // // 參數: // user: // The user whose role names to retrieve. // // 返回結果: // The System.Threading.Tasks.Task that represents the asynchronous operation, containing // a list of role names. [AsyncStateMachine(typeof(UserManager<>.<GetRolesAsync>d__105))] public virtual Task<IList<string>> GetRolesAsync(TUser user);
這樣,就出現了不太方便的問題,刪除用戶角色方法RemoveFromRoleAsync(),需要使用“NormalizedName”,而identity獲取的當前用戶現有角色只能使用GetRolesAsync(),該方法獲得的是角色的“Name”。
所以想當然的代碼(如下)不會出現編譯錯誤,同樣也不會出現運行錯誤,但實際運行后,應該被刪除的角色實際上刪除不了:
var nowRoles = _userManager.GetRolesAsync(user).Result; //得到的nowRoles是角色的Name await _userManager.RemoveFromRolesAsync(user, nowRoles); //這里需要的是角色的NormalizedName
所以,只能想辦法得到當前用戶角色的“NormalizedName”,再傳遞給RemoveFromRoleAsync()。
這面這個辦法比較繁瑣,但想不到更簡單的辦法。
var normalizedName = allRoles.Where(r => r.Name == nowRole).First().NormalizedName;
其中:allRoles是這樣得到的
var allRoles = _roleManager.Roles;
整個代碼是這樣的:
var allRoles = _roleManager.Roles; //系統中所有的角色 var nowRoles = _userManager.GetRolesAsync(user).Result; //該用戶現有的角色“Name” foreach (var nowRole in nowRoles) { var normalizedName = allRoles.Where(r => r.Name == nowRole).First().NormalizedName;//取得現有角色的NormalizedName await _userManager.RemoveFromRoleAsync(user, normalizedName); //刪除不要的角色 } await _userManager.AddToRolesAsync(user, selectedRoles); //添加需要的角色 await _userManager.UpdateAsync(user); //完成儲存
上面代碼沒有進行針對性的添加,代碼有些繁雜,不過這樣也不會出現錯誤,省事兒。
至此,結束。
記錄,備查。