How to access User.Identity in BaseController

BCC_DEV 1 Reputation point
2022-04-07T17:57:15.173+00:00

When accessing the current user in my Windows authenticated .net core mvc app, User.Identity.Name returns Domain\Username. I am trying to implement a custom base controller so that I can change the User.Identity.Name to just Username and save it to a field for every controller that extends my base controller. I created an abstract class BaseController but when I try to access User.Identity.Name I get a null reference exception. I also tried Dependency Injection to use the HttpContextAccessor but then every controller that extends my BaseController gets an error. Here are the examples of what I tried:

public abstract class BaseController : Controller
{
    public readonly username;

    public BaseController()
    {
        username = User.Identity.Name.Split("\\")[1]; // Null reference exception
    }
}


public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
}

public abstract class BaseController : Controller
{
    public readonly username;

    public BaseController(IHttpContextAccessor httpContextAccessor)
    {
        username =httpContextAccessor.HttpContext.User.Identity.Name.Split("\\")[1];
    }
}

public HomeController : BaseController // Won't compile
{
    public IActionResult Index() 
    {
        ViewData["CurrentUser"] = username;
        return View();
    }
}

How can I do this?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,188 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. AgaveJoe 26,136 Reputation points
    2022-04-07T20:06:21.597+00:00

    The user principal is not available in any controller constructor. Create an extension method if all you want to do is split by "\".

    public static class ExtensionMethods  
    {  
        public static string GetUsername(this ClaimsPrincipal User)  
        {  
            return User.Identity.Name.Split("\\")[1];  
        }  
    }  
    

    Implementation is below but the code must be within an action.

    User.GetUsername()  
      
    

    Reference documentation
    Extension Methods (C# Programming Guide)


  2. Bruce (SqlWork.com) 56,766 Reputation points
    2022-04-08T15:47:03.67+00:00

    also there is no good reason to inject an HttpContextAccessor into a controller. there is a performance hit, you use the controller property .HttpContext

    just add a UserName property to the base controller:

    public abstract class BaseController : Controller
    {
           protected string? Username => User?.Identity?.Name?.Split("\\");
    }
    
    0 comments No comments