Can't get UserManager from OwinContext in apicontroller

70,098

Solution 1

I really misunderstood your question earlier. You are just missing some using statements, I think.

The GetOwinContext().GetUserManager<ApplicationUserManager>() is in Microsoft.AspNet.Identity.Owin.

So try add this part:

using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity; // Maybe this one too

var manager = HttpContext.Current.GetOwinContext().GetUserManager<UserManager<User>>();

Solution 2

This extension method may be a better solution if you want to unit test your controllers.

using System;
using System.Net.Http;
using System.Web;
using Microsoft.Owin;

public static IOwinContext GetOwinContext(this HttpRequestMessage request)
{
    var context = request.Properties["MS_HttpContext"] as HttpContextWrapper;
    if (context != null)
    {
        return HttpContextBaseExtensions.GetOwinContext(context.Request);
    }
    return null;
}

Usage:

public ApplicationUserManager UserManager
{
   get
   {
      return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
   }
   private set
   {
      _userManager = value;
   }
}

Solution 3

This single line of code saved my day...

       var manager = 
       new ApplicationUserManager(new UserStore<ApplicationUser>(new ApplicationDbContext()));

You can use it within a controller action to get an instance of UserManager.

Share:
70,098
Marc
Author by

Marc

SOreadytohelp #SOreadytohelp

Updated on July 05, 2022

Comments

  • Marc
    Marc almost 2 years

    I'm following a Microsoft sample to implement email validation with Identity 2.0.0

    I'm stuck at this part

    public ApplicationUserManager UserManager
    {
       get
       {
          return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
       }
       private set
       {
          _userManager = value;
       }
    }
    

    This works in an controller but HttpContext doesn't contain any GetOwinContext method in an ApiController.

    So I tried HttpContext.Current.GetOwinContext() but the method GetUserManager doesn't exist.

    I can't figure out a way to get the UserManager I build in Startup.Auth.cs

    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        //Configure the db context, user manager and role manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
        ...
    }
    

    this line

    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    

    calls the following function to configure the UserManager

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
         var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
         //Configure validation logic for usernames
         manager.UserValidator = new UserValidator<ApplicationUser>(manager)
         {
             AllowOnlyAlphanumericUserNames = false,
             RequireUniqueEmail = true
         };
    
         // Configure user lockout defaults
         manager.UserLockoutEnabledByDefault = true;
         manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
         manager.MaxFailedAccessAttemptsBeforeLockout = 5;
    
         manager.EmailService = new EmailService();
    
         var dataProtectionProvider = options.DataProtectionProvider;
         if (dataProtectionProvider != null)
         {
             manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
         }
         return manager;
    }
    

    How can I access this UserManager in an ApiController?

  • Marc
    Marc almost 10 years
    That's what I used to do but the options I add in the create function are not there.
  • Robert Achmann
    Robert Achmann over 9 years
    Would it be safer overall to use : System.Web.HttpContext.Current.Request.GetOwinContext().GetU‌​serManager....
  • Rikard
    Rikard over 8 years
    @RobertAchmann I can't see why that should be safer or even better because HttpContext.Current is a static property returning the current HttpContext for the thread.
  • MPavlak
    MPavlak over 8 years
    This is the better answer and should be the accepted one. Does not rely on HttpContext.Current.
  • Chef_Code
    Chef_Code about 8 years
    I totally agree, the HttpContext.Current introduces a dependency to System.Web, which is not available in self-hosted scenarios. Request.GetOwinContext() is injected, therefore allowing for test-ability. The latter is neither.
  • Chef_Code
    Chef_Code about 8 years
    BTW... Request.GetOwinContext() is defined in the Microsoft.AspNet.WebApi.Owin nuget package
  • dan richardson
    dan richardson over 7 years
    This answer doesn't actually answer the question as HttpContext is not accessible in an ApiController. Using the extension in System.Net.Http from System.Web.Http.Owin.dll works fine from the nuget plugin - nuget.org/packages/Microsoft.AspNet.WebApi.Owin
  • petrosmm
    petrosmm over 5 years
    This helped me avoid exceptions that were getting thrown when i would use HttpContext.Current.GetOwinContext(). This is much better.
  • ScottB
    ScottB over 4 years
    Agree this is the better answer as it avoids potential exception issues around HttpContext.Current. You can then just write Request?.GetOwinContext().