2017-07-03 45 views
0

ASP.NET Identity 2 or 3中,是否可以獲取類級別的用戶信息?情景如下:應用中只有兩個角色,即AdminRoleRegRole。 AdminRole中的用戶可以充當UserRole中的用戶,只需從AdminRole用戶可用的下拉列表中選擇一個用戶名即可。我需要做的是,如果管理員從主頁的下拉列表中選擇一個用戶,我需要將所選用戶的名稱分配給一個類(即Controller)級變量,以便用戶名可以用於所有用戶該控制器的操作方法(一個類)。我嘗試以下,但它在if (User.Identity.Name == "Admin")線以下的代碼拋出NullException:在ASP.NET標識中獲取類級別的用戶信息

NullReferenceException: Object reference not set to an instance of an object.

家庭控制器 [如果管理員從下拉菜單中選擇一個用戶名]

public class HomeController : Controller 
{ 
    ... 
    [HttpPost] 
    public IActionResult ChooseUser(string selectedUser) 
    { 
     HttpContext.Session.SetString(SessionKeySelUser, selectedUser); 

     return View(); 
    } 
} 

其他控制器 [我想在以下控制器的所有操作方法中使用選定的用戶名稱]

public class TestController : Controller 
{ 
    private MyProjContext _context; 
    private string _userName; 

    public TestController (MyProjContext context) 
    { 
    _context = context; 

    if (User.Identity.Name == "Admin") 
     _userName = HttpContext.Session.GetString("selectedUser"); //This session variable was assigned the user name value when the admin had selected the user name from the dropdown on the home page 
    } 
} 

//use the class level variable _userName in all action methods like the one below 
public IActionResult TestAction() 
{ 
    _context.Orders.Where(ord => ord.Seller == _userName); 

    return View(); 
} 

.... 

回答

0

如果您使用的是Identity 3,則必須獲得UserManager的實例才能獲取當前登錄的用戶。

可以使用iOC得到UserManager一個實例,然後使用UserManagerGetUserAsync方法來獲取當前用戶的對象模型。

protected readonly UserManager<AppUser> UserManager; 
private Task<AppUser> GetCurrentUserAsync() => UserManager.GetUserAsync(HttpContext.User); 

public TestController(UserManager<AppUser> userManager) 
{ 
    UserManager = userManager; 
} 

你的條件是可以改變的,因爲這:

var curUser = await GetCurrentUserAsync(); 
if (curUser.Name == "Admin") 
     _userName = HttpContext.Session.GetString("selectedUser"); //This session variable was assigned the user name value when the admin had selected the user name from the dropdown on the home page 

既然你正試圖從構造函數訪問它,你可以在前面加Result,使其同步。正如您在註釋中報告的那樣,構造類時,控制器的HttpContext爲null。不過,您可以從IHttpContextAccessor訪問它。

public TestController(UserManager<AppUser> userManager, IHttpContextAccessor httpContextAccessor) 
{ 
    UserManager = userManager; 
    var curUser = UserManager.GetUserAsync(httpContextAccessor.HttpContext.User).Result; 
    if (curUser.Name == "Admin") 
     _userName = HttpContext.Session.GetString("selectedUser"); 
} 

如果使用Identity,我相信IHttpContextAccessor注入管道。如果它返回null,則必須將它作爲單例添加到您的Startup類中。

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
+0

我認爲'Task '的意思是'Task '。無論如何,在線'GetCurrentUserAsync.Name ==「管理員」我收到錯誤:**任務'不包含名稱**的定義。 – nam

+0

你說得對。我剛剛更新了答案。我使用自定義用戶,這就是爲什麼我命名類AppUser。默認值是ApplicationUser。 –

+0

是的,但同樣的錯誤依然存在。 – nam