UserTokenProvider/DataProtectorTokenProvider在代码优先迁移种子方法期间出现N



模式更新得很好,但是由于NullReferenceException, seed方法没有运行。其他一切似乎都很好,包括能够在网站运行时为密码重置发出令牌等等。它只在Seed方法运行时这样做。我想我只是在添加DataProtectorTokenProvider之后才开始得到这个。什么好主意吗?

编辑:当然这个NullReferenceException不应该发生在所有,所以什么是NullReferenceException,我该如何修复它?

编辑:也许不是。我是不是漏掉了什么重要的东西?这行代码:

UserTokenProvider = new DataProtectorTokenProvider<AppUser> (dataProtectionProvider.Create("ASP.NET Identity")) { TokenLifespan = TimeSpan.FromDays(90d) }; 

DataProtectorTokenProvider实例化在Seed方法期间会导致除null以外的任何结果吗?因为站点/应用程序没有运行/还没有启动,这就是OWIN的工作方式。谢谢。

下面是PMC的输出:

Running Seed方法。

系统。NullReferenceException:对象引用没有设置为对象的实例。

在Identity.AppUserManager . .在IdentityAppUserManager.cs:第25行

在Migrations.Configuration

。种子(EFDbContext上下文)在MigrationsConfiguration.cs:第49行

System.Data.Entity.Migrations.DbMigrationsConfiguration的1。利用(DbContext上下文)

System.Data.Entity.Migrations.DbMigrator.SeedDatabase ()

System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase ()

在System.Data.Entity.Migrations.DbMigrator

。升级(IEnumerable ' 1 pendingMigrations, String targetMigrationId, String lastMigrationId)

在System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator

。升级(IEnumerable ' 1 pendingMigrations, String targetMigrationId, String lastMigrationId)

在System.Data.Entity.Migrations.DbMigrator

。UpdateInternal(字符串targetMigration)

在System.Data.Entity.Migrations.DbMigrator灵活;> c__DisplayClassc.b__b ()

在System.Data.Entity.Migrations.DbMigrator

。EnsureDatabaseExists (Action mustSucceedToKeepDatabase)

在System.Data.Entity.Migrations.Infrastructure.MigratorBase

。EnsureDatabaseExists (Action mustSucceedToKeepDatabase)

在System.Data.Entity.Migrations.DbMigrator

。更新(字符串targetMigration)

在System.Data.Entity.Migrations.Infrastructure.MigratorBase

。更新(字符串targetMigration)

System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run ()

在System.AppDomain

。DoCallBack (CrossAppDomainDelegate callBackDelegate)

在System.AppDomain

。DoCallBack (CrossAppDomainDelegate callBackDelegate)

在System.Data.Entity.Migrations.Design.ToolingFacade

。运行(BaseRunner runner)

在System.Data.Entity.Migrations.Design.ToolingFacade

。Update(String targetMigration, Boolean force)

在System.Data.Entity.Migrations.UpdateDatabaseCommand灵活;> c__DisplayClass2灵活;.ctor> b__0 ()

在System.Data.Entity.Migrations.MigrationsDomainCommand

。执行(Action命令)

对象引用未设置为对象的实例。

下面是配置代码:
internal sealed class Configuration: DbMigrationsConfiguration<Website.Domain.Concrete.EFDbContext>
{       
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        ContextKey = "Website.Domain.Concrete.EFDbContext";
    }
    protected override void Seed(Concrete.EFDbContext context) 
    {         
        // This line is where we hit the exception
        AppUserManager userManager = new AppUserManager(new UserStore<AppUser>(context));
        AppRoleManager roleManager = new AppRoleManager(new RoleStore<AppRole>(context));
        ...

下面是AppUserManager代码:

public class AppUserManager : UserManager<AppUser> 
{     
    public AppUserManager(IUserStore<AppUser> store) 
        : base(store) 
    {
        IDataProtectionProvider dataProtectionProvider = IdentityConfig.DataProtectionProvider; 
        // This is causing the NullReferenceException
        UserTokenProvider = new DataProtectorTokenProvider<AppUser>(dataProtectionProvider.Create("ASP.NET Identity")) { TokenLifespan = TimeSpan.FromDays(90d) }; 
    }
    public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {           
        EFDbContext db = context.Get<EFDbContext>();
        AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db));
        manager.PasswordValidator = new PasswordValidator 
        {
            RequiredLength = 8,                 
            RequireNonLetterOrDigit = false,
            RequireDigit = false,
            RequireLowercase = false,
            RequireUppercase = false             
        };
        manager.UserValidator = new UserValidator<AppUser>(manager) 
        {
            AllowOnlyAlphanumericUserNames = true,
            RequireUniqueEmail = true
        };
        return manager;
    }       
}

这里是IdentityConfig文件。我有这个而不是启动文件我告诉Owin在启动时运行它在web。config

的appsettings中使用这个键
<add key="owin:AppStartup" value="Website.Domain.App_Start.IdentityConfig" />:
namespace Website.Domain.App_Start
{
    public class IdentityConfig 
    {    
        public static IDataProtectionProvider DataProtectionProvider { get; set; } 
        public void Configuration(IAppBuilder app)
        {
            DataProtectionProvider = app.GetDataProtectionProvider(); 
            app.CreatePerOwinContext<EFDbContext>(EFDbContext.Create);
            app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
            app.CreatePerOwinContext<AppRoleManager>(AppRoleManager.Create); 
            app.CreatePerOwinContext<AppSignInManager>(AppSignInManager.Create);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/account/login")
            });
        }
    }
}

失败是因为

IDataProtectionProvider dataProtectionProvider = IdentityConfig.DataProtectionProvider;

将返回null,除非应用程序正在运行。因此,这在迁移期间会失败。

修复:

if (dataProtectionProvider != null)
{
    UserTokenProvider = new DataProtectorTokenProvider<AppUser>(dataProtectionProvider.Create("ASP.NET Identity")) { TokenLifespan = TimeSpan.FromDays(90d) }; 
}

相关内容

  • 没有找到相关文章

最新更新