在MVC5中,我通过覆盖控制器中的Initialize
方法将当前登录用户的ID初始化为私有域。
public class BaseControllerConstructor: Constructor
{
protected UserProfile _currentUserProfile;
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
if (User.Identity.IsAuthenticated)
{
_currentUserId = User.Identity.GetUserId();
_currentUserProfile = LoadUserProfile(_currentUserId);
}
}
}
在MVC6控制器中没有Initialize
。
当我尝试在构造函数中获取当前登录用户的ID时,User
和HttpContext
为null
。
public BaseControllerConstructor()
{
// HttpContext is null
string _currentUserId = HttpContext.User.GetUserId();
_currentUserProfile = LoadUserProfile(_currentUserId);
}
如何在MVC6中实现这一目标?具体来说:如何获取当前登录用户的用户ID并在_currentUserId
中初始化BaseControllerConstructor
?
然后在Controller动作中调用:
class Controller: BaseControllerConstructor
{
public ActionResult Action()
{
foo(_currentUserProfile);
}
}
更新:我使用依赖注入解决了这个问题。请看下面的答案。
答案 0 :(得分:5)
我已使用依赖注入和IHttpContextAccessor
类来解决此问题,以访问HttpContext.User
。
实施注册为Startup.cs
的服务。
// The interface for the service.
public interface IAccountService
{
User CurrentUser { get; }
string CurrentUserId { get; }
}
// The class which implements the interface
public class AccountService : IAccountService
{
private IHttpContextAccessor _httpContextAccessor;
// This is a custom services which has access to the business model and the data model
private IUserService _userService;
private string _currentUserId;
private User _currentUser;
public AccountService(IHttpContextAccessor httpContextAccessor, IUserService currentUser)
{
_httpContextAccessor = httpContextAccessor;
_coreServiceProvider = coreServiceProvider;
_currentUserId = null;
_currentUser = null;
}
public User CurrentUser
{
get
{
if (_currentUser != null)
{
return _currentUser;
}
if (string.IsNullOrEmpty(_currentUserId))
{
// Get the user ID of the currently logged in user.
// using System.Security.Claims;
_currentUserId = _httpContextAccessor.HttpContext.User.GetUserId();
}
if (!string.IsNullOrEmpty(_currentUserId))
{
_currentUser = _userService.Find(_currentUserId);
if (_currentUser == null)
{
string errMsg = string.Format("User with id {0} is authenticated but no user record is found.", _currentUserId);
throw new Exception(errMsg);
}
}
return _currentUser;
}
}
public string CurrentUserId
{
get
{
if (!string.IsNullOrEmpty(_currentUserId))
{
return _currentUserId;
}
// Get the user ID of the currently logged in user.
// using System.Security.Claims;
_currentUserId = _httpContextAccessor.HttpContext.User.GetUserId();
return _currentUserId;
}
}
}
在课程Startup
方法ConfigureServices
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Register UserService a custom class which has access to the user profiles
// This is injected.
services.AddScoped<IUserService, UserService>();
// Register the IAccountService which is injected in the controller
services.AddScoped<IAccountService, AccountService>();
}
}