我在帐户控制器中获取正确的UserManager实例时出现问题。目前,我无法重置密码以作为我的提供商工作,其他设置被忽略。
在Startup中 - void ConfigureAuth(IAppBuilder app)我有以下内容:
app.CreatePerOwinContext<ViewingBookerDatabaseContext>(ViewingBookerDatabaseContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
然后在AccountManager类中,上面引用的方法Create包含以下内容:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
// Configure the application user manager
public ApplicationUserManager(ApplicationUserStore store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new ApplicationUserStore(new ViewingBookerDatabaseContext()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
现在,在安装IoC之前,这种方法很有用 - 在本例中是StrcutureMap。控制器的IoC以下列模式注册:
Scan(scan =>
{
scan.TheCallingAssembly();
scan.With(new ControllerConvention());
});
public class ControllerConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (type.CanBeCastTo(typeof(Controller)) && !type.IsAbstract)
{
registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
}
}
}
然后在我的AccountController中引用UserManager,如下所示:
private ApplicationUserManager _userManager;
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
private IAuthenticationManager _authenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager, ViewingBookerDatabaseContext context, CurrentUser currentUser, Logger logger, EmailService emailService)
{
UserManager = userManager;
_context = context;
_currentUser = currentUser;
_logger = logger;
_emailService = emailService;
}
现在,UserManager用于我的密码重置,帐户创建等。安装IoC后,我收到“没有ITokenProvider已注册”密码重置,带有@的帐户名在创建用户时返回无效等。看起来像AccountController的ApplicationUserManager实例不是通过ApplicationUserManager类的Create()方法创建的。
任何人都可以指向我对结构图的正确实现,因此它调用Create来获取AccountUserManager的实例,而不是返回不包含ITokenProvider规范的该类的通用实例。等?
感谢您的帮助。
答案 0 :(得分:4)
好的伙计们。由于没有人回复这么久,不得不做一些进一步的研究,并提出以下,可能不是最优雅,这是一个有效的解决方案:
<强> 1。 Startup.cs - 删除以下行
app.CreatePerOwinContext<ViewingBookerDatabaseContext> (ViewingBookerDatabaseContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
<强> 2。在Startup.cs中引入新变量
public static IDataProtectionProvider DataProtectionProvider {get;私人集; }
然后,将它在public void ConfigureAuth(IAppBuilder应用程序)中设置为以下:
DataProtectionProvider = app.GetDataProtectionProvider();
第3。 ApplicationUserManager或您调用的任何内容,删除静态Create方法并将其构造函数更改为以下内容:
public ApplicationUserManager(ApplicationUserStore store)
: base(store)
{
// Configure validation logic for usernames
UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
// Configure user lockout defaults
UserLockoutEnabledByDefault = true;
DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
MaxFailedAccessAttemptsBeforeLockout = 5;
}
对于密码重置ITokenProvider,只需引用Startup的DataProtectionProvider变量,如下所示:
if (Startup.DataProtectionProvider != null)
UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(Startup.DataProtectionProvider.Create("ASP.NET Identity"));
最后......
在AccountController.cs中- 删除对ApplicationUserManager的getter的任何引用,并重用StructureMap在控制器构造函数中提供的实例。
public AccountController(ApplicationUserManager userManager)
{
_userManager = userManager;
所以你要调用_userManager对象方法
REMOVE IF YOU HAVE IT IN YOUR CONTROLLER:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
答案 1 :(得分:1)
您可以注册创建回调以在静态创建之外设置这些属性。以下是我如何完成同样的事情:
$collection = $this->getMock('MongoCollection', ['find', 'findOne'], [], '', false);
$collection->method('find')->will($this->returnValue([
[['_id' => 'aaa'], ['content'], 'ccc']
]));
$collection->method('findOne')->will($this->returnValue([
[['_id' => 'aaa'], ['content'], 'ccc']
]));