简单注入器 - 值不能为空。参数名称:userManager

Simple Injector - Value cannot be null. Parameter name: userManager

我正在尝试使用 Simple Injector 进行 ASP.NET 身份设置,但我遇到了一个又一个问题。我想我快接近了,但现在我收到一条错误消息

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.SignInManager2..ctor(UserManager2 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.IdentityFactoryProvider1.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

我在这里收到错误消息:

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);
    }
}

启动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"));
        }
    }
}   

AccountControllerManageController 的设置与此类似:

    private SignInManager<ApplicationUser, string> _signInManager;
    private ApplicationUserManager _userManager;

    public AccountController(ApplicationUserManager userManager, SignInManager<ApplicationUser, string> signInManager)
    {
        _userManager = userManager;
        _signInManager = signInManager;
    } 

我是否为 ApplicationUserManager 注册了错误?

如果你分析堆栈跟踪,问题应该变得清晰:

  • Microsoft.AspNet.Identity.Owin.SignInManager<TUser, TKey> 的构造函数被传递给 userManager 构造函数参数的 null 值。
  • 通过传递 userManager 参数,从应用程序 ILETSB.MCLETC.UI.ApplicationSignInManager 的构造函数调用 Microsoft.AspNet.Identity.Owin.SignInManager<TUser, TKey> 构造函数。
  • ILETSB.MCLETC.UI.ApplicationSignInManager 的构造函数是从 ApplicationSignInManager 自己的 Create 方法中调用的。

换句话说,静态 ApplicationSignInManager.Create 方法正在为 ApplicationSignInManager 构造函数提供空值。

分析到此为止,因为您还没有提供 Create 方法的详细信息。

尝试通过放置断点来调试 Create 方法,以分析发生了什么以及为什么值为 null