简体   繁体   中英

How to get logged-in user name in the constructor of a controller in ASP.NET Core Identity

I'm using ASP.NET Core 1.1 and Identity 3.0 . I'm trying to access the logged in user's login name in the constructor of of a controller as follows. But I'm getting the NullReferenceException . However, I can get the user name in any action method of the controller as shown below. Question : How can I get the user name inside the constructor of the controller so I can use it anywhere in any action method of the controller. It seems I may have to do some sort of dependency injection for this (but this is just a guess).

public class TestController : Controller
{
    private ProjNameContext _context;

    string selUser = "";

    public TestController(ProjNameContext context)
    {
        _context = context;
        selUser = User.Identity.Name; //Here I get error: Object reference not set to an instance of an object.
    }

    [HttpGet]
    public IActionResult TestAction()
    {
        selUser = User.Identity.Name; //Here the user name (login name) is not null
       .....
    }

    ....
}

In short, you can't do that in your constructor (at least not directly) because it's too early in the request lifecycle. You could use an attribute that would inject the value into somewhere (perhaps ViewData but I'm not sure that's valid in Core) but if the real goal is just to cache the username for use later on in an action method, then I would just create a method that does that instead. You could even put it in a base controller class for use in any action across your project. For example:

public class BaseController : Controller
{
    private string _username;

    protected string Username
    {
        get
        {
            if (_username == null)
            {
                _username = User.Identity.Name;
            }
            return _username;
        }
    }
}

Now just make your controllers inherit from this and you get automatic access to this property. For example:

public class TestController : BaseController
                            //^^^^^^^^^^^^^^
{
    private ProjNameContext _context;

    public TestController(ProjNameContext context)
    {
        _context = context;
    }

    [HttpGet]
    public IActionResult TestAction()
    {
        Now you don't need to cache the username yourself as it's done for you.
        var username = Username;
        //Do something with username
    }

}

You can use base controller in which you can write your own method to get logged in user username.

public class BaseControler : Controller
{
    public string GetUsername()
    {
        if (User != null)
        {
            return User.Identity.Name;
        }
        else if (System.Web.HttpContext.Current.User != null)
        {
            return System.Web.HttpContext.Current.User.Identity.Name;
        }
        return string.Empty;
    }
}

Then in your real controller which inherits from Base controller you can get username in constructor.

public class MyController: BaseController
{
    private string username;

    public MyController()
    {
        username = GetUsername();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM