1

I'm working on a WebApi project with Asp.Net.Identity v2 (with AspNetUser modified to use int IDs). I wanted to do a bit of refactoring by creating a base class for all my web api controllers. In particular, I wanted the MyBaseController class to encapsulate the logic of getting the current user id.

Previously, each action method in each controller called User.Identity.GetUserId<int>(). it was cumbersome but worked.

Now I decided to encapsulate that call either in the base class's constructor or in its property. However, it doesn't work: The Identity object I get is empty (IsAuthenticated = false, Name = null...), and GetUserId<int>() always returns 0.

Apparently it is only inside an action method that Identity is populated and GetUserId<int>() returns a correct result?

Here is basically what I get:

public class MyBaseController : ApiController
{
    public int UserId => User.Identity.GetUserId<int>(); // **this always returns 0**
    public MyBaseController() : base() 
    { var userId = User.Identity.GetUserId<int>(); // **this is always 0** }

    protected override void Initialize(HttpControllerContext controllerContext)
    {
        base.Initialize(controllerContext);
        var userId = User.Identity.GetUserId<int>(); // **also 0**
    }

    public IHttpActionResult Get() {
        var userId = User.Identity.GetuserId<int>(); // **the only place where it returns userId properly**
       // some code ... 
    }
}

Is there a way to grab User.Identity other than in an action method to do something with it in a base class?

The project was initially created in VS 2013 with MVC 5 / WEbapi 2, now migrated to VS2015

AunAun
  • 1,423
  • 2
  • 14
  • 25

2 Answers2

1

You cannot access User.Identity before authorization. See the APIController life cycle here or on MSDN.

The information is not yet available in the constructor or in Initialize().

devio
  • 36,858
  • 7
  • 80
  • 143
0

You can use a property in the base controller:

public abstract class MyBaseController : ApiController
{
    public int UserID
    {
        get { return User.Identity.GetUserId<int>(); }
    }
}

public class MyNormalController : MyBaseController
{
    public ActionResult Index()
    {
        var userId = UserID; // put in variable to avoid multiple calls
       // some code ... 
    }
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
  • Thanks @PeterB, but what if I want to do smth with it in my base class? e.g. suppose that I want to load some info based on the user id or pass it to some service from within my base class? no way? – AunAun Mar 25 '16 at 14:14
  • You can for sure if it happens during an Action which makes a call to the base class. Outside of that I'm not sure. The lifespan or availability of the corresponding HttpContext could be short or long, but I just don't know. – Peter B Mar 25 '16 at 14:30