获取当前在控制器构造函数ASP.NET 5 MVC6中登录的用户标识

fer*_*adz 2 c# asp.net asp.net-core-mvc

在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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在MVC6控制器没有Initialize.

当我试图让当前登录的ID的用户在构造函数中,UserHttpContextnull.

public BaseControllerConstructor()
{
    // HttpContext is null      
    string _currentUserId = HttpContext.User.GetUserId();
    _currentUserProfile = LoadUserProfile(_currentUserId);
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能在MVC6中实现这一目标?具体来说:如何获取当前登录用户的用户ID并_currentUserIdBaseControllerConstructor?中初始化?

然后在Controller动作中调用:

class Controller: BaseControllerConstructor
{
    public ActionResult Action()
    {
        foo(_currentUserProfile);
    }       
}
Run Code Online (Sandbox Code Playgroud)

更新:我使用依赖注入解决了这个问题.请看下面的答案.

fer*_*adz 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在类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>();
    }
}
Run Code Online (Sandbox Code Playgroud)