繁体   English   中英

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

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

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

值不能为空。

参数名称:userManager

说明:在执行当前 Web 请求期间发生未处理的异常。 请查看堆栈跟踪以获取有关错误及其在代码中的来源的更多信息。

异常详细信息:System.ArgumentNullException:值不能为空。 参数名称:userManager

[ArgumentNullException:值不能为空。 参数名称: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(IdentityFactoryOptions 1 options, IOwinContext context) in MCLETC.UI\\App_Start\\IdentityConfig.cs:53 Microsoft.AspNet.Identity.Owin.IdentityFactoryProvider (IdentityFactoryOptions`1选项,IOwinContext 上下文) +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.Compiler Services.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);
    }
}

启动类:

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

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

这是分析可以走多远,因为您还没有提供Create方法的详细信息。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM