I'm trying to get ASP.NET Identity setup with Simple Injector and I'm having problem after problem. I think I'm getting close, but now I'm getting an error saying
Value cannot be null.
Parameter name: userManager
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentNullException: Value cannot be null. Parameter name: userManager
[ArgumentNullException: Value cannot be null. Parameter name: userManager] Microsoft.AspNet.Identity.Owin.SignInManager
2..ctor(UserManager
2 userManager, IAuthenticationManager authenticationManager) +81 ILETSB.MCLETC.UI.ApplicationSignInManager..ctor(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) in MCLETC.UI\App_Start\IdentityConfig.cs:42 MCLETC.UI.ApplicationSignInManager.Create(IdentityFactoryOptions1 options, IOwinContext context) in MCLETC.UI\App_Start\IdentityConfig.cs:53 Microsoft.AspNet.Identity.Owin.IdentityFactoryProvider
1.Create(IdentityFactoryOptions`1 options, IOwinContext context) +14 Microsoft.AspNet.Identity.Owin.d__5.MoveNext() +89 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +102 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +64 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__7.MoveNext() +179 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +102 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +64 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__12.MoveNext() +180 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +69 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +64 System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +389 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +50 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163
I'm getting the error message here:
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
Startup class:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app, Container container)
{
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.CreatePerOwinContext(() => container.GetInstance<ApplicationUserManager>());
// Nothing modified below (template code)
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
}
}
SimpleInjectorInitializer:
public class SimpleInjectorInitializer
{
/// <summary>Initialize the container and register it as MVC5 Dependency Resolver.</summary>
public static Container Initialize(IAppBuilder app)
{
var container = GetInitializeContainer(app);
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
return container;
}
private static Container GetInitializeContainer(IAppBuilder app)
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
// IoC for ASP.NET Identity
container.RegisterInstance(app);
container.Register<ApplicationUserManager>(Lifestyle.Scoped);
container.Register(() => new ApplicationDbContext("Your constring goes here"), Lifestyle.Scoped);
container.Register<IUserStore<ApplicationUser>>(() => new UserStore<ApplicationUser>(container.GetInstance<ApplicationDbContext>()), Lifestyle.Scoped);
container.RegisterInitializer<ApplicationUserManager>(manager => InitializeUserManager(manager, app));
container.Register<SignInManager<ApplicationUser, string>, ApplicationSignInManager>(Lifestyle.Scoped);
container.Register(() => container.IsVerifying ? new OwinContext(new Dictionary<string, object>()).Authentication : HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
// Register all controllers
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
//Register Modules
BusinessModule.RegisterServices(container);
WebModule.RegisterServices(container);
return container;
}
private static void InitializeUserManager(ApplicationUserManager manager, IAppBuilder app)
{
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
//Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator()
{
RequiredLength = 8,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 3;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = app.GetDataProtectionProvider();
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
Both AccountController
and ManageController
are setup similar to this:
private SignInManager<ApplicationUser, string> _signInManager;
private ApplicationUserManager _userManager;
public AccountController(ApplicationUserManager userManager, SignInManager<ApplicationUser, string> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
Am I registering something wrong for the ApplicationUserManager
?
If you analyze the stack trace, the problem should become clear:
Microsoft.AspNet.Identity.Owin.SignInManager<TUser, TKey>
is passed a null
value for the userManager
constructor parameter.Microsoft.AspNet.Identity.Owin.SignInManager<TUser, TKey>
constructor is called from the constructor of your application's ILETSB.MCLETC.UI.ApplicationSignInManager
by passing the userManager
parameter through.ILETSB.MCLETC.UI.ApplicationSignInManager
's constructor is invoked from within the ApplicationSignInManager
's own Create
method.In other words, the static ApplicationSignInManager.Create
method is supplying the ApplicationSignInManager
constructor with a null value.
This is how far the analysis can go, because you haven't provided the details of the Create
method.
Try debugging the Create
method by placing break points to analyze what's going on and why the value is null
.