ApplicationUserManager不使用我的自定义UserStore实现

时间:2015-02-10 13:18:56

标签: asp.net-mvc asp.net-mvc-5 asp.net-identity asp.net-identity-2

我使用ASP.NET Identity创建了一个新的MVC5应用程序。我没有改变很多文件。这是我得到的错误:

Exception when using ApplicationManager

项目中的以下更改与VisualStudio模板不同:

ApplicationUserManager.cs

public class ApplicationUserManager : UserManager<User>
{
    public ApplicationUserManager(IUserStore<User> userStore)
        : base(userStore)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        // Use DI to resolve the UserStore
        var userStore = (IUserStore<User>) DependencyResolver.Current.GetService(typeof (IUserStore<User>));

        var manager = new ApplicationUserManager(userStore);

        // rest is same as in the template ...
    }
}

我的DependencyResolver是Ninject。我为它创建了以下Binding:

Bind<IMyDbContextFactory>().To<MyDbContextFactory>().InSingletonScope();
Bind<IUserStore<User>>().To<UserStore>().WithConstructorArgument("factory", factory => Kernel.Get<MyDbContextFactory>());

UserStore.cs

public class UserStore : IUserStore<User>,
    IUserLockoutStore<User, string>,
    IUserPasswordStore<User>,
    IUserTwoFactorStore<User, string>,
    IUserEmailStore<User>
{
    private readonly IMyDbContextFactory _factory;

    public UserStore(IMyDbContextFactory factory)
    {
        _factory = factory;
    }

    public void Dispose()
    {
        // Nothing to dispose here
    }

    public Task CreateAsync(User user)
    {
        using (var context = _factory.CreateContext())
        {
            // TODO: Validation
            context.Users.Add(user);
            var result = context.SaveChanges();
            return Task.FromResult(result);
        }
    }

    // the rest of the implementend methods from the interfaces ...
}

为了完整起见,用户实体,DbContext和我用来检索UserStore.cs

中的DbContext的工厂

User.cs

public class User : IUser
{
    public string Id { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Email { get; set; }
    public object PhoneNumber { get; set; }
    public int AccessFailedCount { get; set; }
    public bool LockoutEnabled { get; set; }
    public DateTime? LockoutEndDateUtc { get; set; }
    public bool TwoFactorEnabled { get; set; }

    public virtual ICollection<UserRole> ApplicationUserRoles { get; set; }
    public virtual ICollection<UserLogin> ApplicationUserLogins { get; set; }
}

MyDbContextFactory.cs

public class MyDbContextFactory : IMyDbContextFactory
{
    public IMyDbContext CreateContext()
    {
        return new MyDbContext();
    }
}

MyDbContext.cs

public class MyDbContext : DbContext, IMyDbContext
{
    public MyDbContext()
        : base("MyDbContextConnection")
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;

        Database.Initialize(true);
    }

    // DbSets, OnModelCreating and other stuff ...
}

异常意味着UserManager为null。但事实并非如此:

enter image description here

似乎ApplicationUserManager并没有真正使用(或设置)我注入的UserStore。但那为什么呢?

1 个答案:

答案 0 :(得分:2)

好的,我发现了,但这是一个艰难的。

UserStore调用ApplicationUserManager的第一种方法是SetPasswordHashAsync。 (不要问我为什么 - .-)

我对该方法的实现返回null。出于两个原因,这是错误的

  1. 我不应该写return null;而是return Task.FromResult<Task>(null);,因为它是异步方法。 (或抛出异常)。因此,我收到了无用的YSOD。
  2. UserManager首先调用SetPasswordHashAsync。再说一遍,不要问我为什么。由于我使用/Account/Register动作来注册新用户,因此我根本没想到UserManager会首先尝试设置密码。我的意思是,还没有用户。这就是我想注册一个的原因。 WTF?
  3. 总结一下:UserManager确实使用了我的UserStore,但没有像我预期的那样。