Reputation: 2337
I have an asp.net core 2.2 mvc project setup with windows authentication, my razor layout has this @User.Identity.Name which works great, but in my controller, User.Identity is null! any idea what I am doing wrong?
here's a sample of my controller:
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using UI.Models;
namespace UI.Controllers
{
public class HomeController : Controller
{
string shortName = string.Empty;
public HomeController()
{
shortName = User.Identity.Name;
}
public IActionResult Index()
{
return View();
}
}
}
Upvotes: 1
Views: 532
Reputation: 388273
You cannot access User
, HttpContext
, or other related properties within the constructor of a controller. That means that you can access these properties only within an actual controller action, like your Index
method.
To understand this, you need to understand how these controller properties actually work and how the framework will manage the lifetime of a controller. As you may be aware, controllers are short-lived objects that are created temporarily only for the duration of a single request. That means that they will always execute within the scope of a single request.
By that logic, accessing the user or other properties of the HTTP context should work just fine; and it usually is. However, when you inherit those properties from Controller
or ControllerBase
, then those don’t magically have a value. Instead, they will be set explicitly by the framework after it creates the controller.
The logic for this is simlar to this:
// create the controller with its dependencies
var controller = CreateController<HomeController>();
// set the controller context
controller.ControllerContext = context;
// invoke action
controller.Index();
So when the object is constructed and the constructor runs, you can access anything that is a direct dependency of the controller, since the dependency injection container will provide all those values through constructor injection.
Anything else though will not be available automatically. That includes all the default properties that you inherit from Controller
or ControllerBase
. These are usually implicitly set by the ControllerContext
, so you will have to wait for the framework to set those.
Since it is impossible to set a property value before the constructor runs, you will simply not be able to access any of these values within the constructor. So the solution is to move the logic into an action instead. That way, you can access the properties and they will have the proper values.
public class HomeController : Controller
{
public IActionResult Index()
{
var shortName = User.Identity.Name;
return View();
}
}
Upvotes: 4