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

时间:2016-02-13 10:46:43

标签: 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);
        }
    }
}

在MVC6控制器中没有Initialize

当我尝试在构造函数中获取当前登录用户的ID时,UserHttpContextnull

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);
    }       
}

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

1 个答案:

答案 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>();
    }
}