[英]ASP.NET Core 5 MVC: ArgumentNullException: Value cannot be null. (Parameter 'items')
[英]Value cannot be null. (Parameter 'principal') [ Identity ] [ ASP.net core ]
我正在開發一個Asp.Net core
項目,並且使用Identity
框架。
問題:
在 Controller 內部,我嘗試根據User
(他的類型是ClaimsPrincipal
)獲取當前用戶信息,但出現運行時錯誤。
我嘗試什么:
那是我的Controller
代碼
[Authorize]
public class ServiceController : Controller
{
private readonly UserManager<AppUser> _userManager;
private RoleManager<IdentityRole> _roleManager;
private AppUser _currentUser;
private AppRoles _currentUserRole;
public ServiceController(UserManager<AppUser> userManager, RoleManager<IdentityRole> roleManager)
{
_userManager = userManager;
_roleManager = roleManager;
SetCurrentUser();
SetCurrentUserRole();
}
#region Private Methods
private async void SetCurrentUser()
{
var us = User;
_currentUser = await _userManager.GetUserAsync(User);
}
private async void SetCurrentUserRole()
{
string currentUserRoleName = _userManager.GetRolesAsync(_currentUser).Result.FirstOrDefault();
if (User.IsInRole(AppRoles.Admin.ToString()))
{
_currentUserRole = AppRoles.Admin;
}
else if (User.IsInRole(AppRoles.User.ToString()))
{
_currentUserRole = AppRoles.User;
}
}
#endregion
public ActionResult Get()
{
return _currentUserRole switch
{
AppRoles.User => RedirectToAction("Services", "User"),
AppRoles.Admin => RedirectToAction("Services", "Admin"),
_ => RedirectToPage("Login")
};
}
}
我在哪里得到錯誤?
錯誤發生在SetCurrentUser
方法中,Visual Studio 拋出了這個異常:
System.ArgumentNullException: '值不能是 null。 (參數'主要')'
錯誤截圖:
附加信息:
我的項目依賴於.Net 5
請幫助解決這個問題?
User
和HttpContext
尚未在控制器的構造函數中設置(仍然是null
)。 如果要訪問它,請嘗試將IHttpContextAccessor
注入到構造函數中,如下所示:
public ServiceController(UserManager<AppUser> userManager,
RoleManager<IdentityRole> roleManager,
IHttpContextAccessor httpContextAccessor){
var user = httpContextAccessor.HttpContext.User;
//now pass the user above around to use it instead of basing on the property User
//...
}
然而,這種方式並不是每個標准,尤其是當您需要在構造函數中調用async
方法時,根本不應該這樣做。 您的方法甚至使用async void
聲明,這應該絕對避免。 實際上,您想要的是在執行操作之前自動提供一些信息。 這非常適合IActionFilter
或IAsyncActionFilter
(這里使用異步過濾器更好,因為您將在那里調用異步方法)。 因為在 controller 中提供了信息(作為屬性/字段),所以覆蓋 controller 的OnActionExecutionAsync
方法而不是使用我提到的過濾器會更方便。 在這種情況下使用過濾器可能需要您共享周圍的信息(例如通過HttpContext.Items
或請求功能......),這有點不方便。
這是你應該如何做的:
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
await SetCurrentUserAsync();
await SetCurrentUserRoleAsync();
await base.OnActionExecutionAsync(context, next);
}
//adjust your methods
private async Task SetCurrentUserAsync() { ... }
private async Task SetCurrentUserRoleAsync() { ... }
就是這樣,記住在構造函數中刪除你的等效代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.