【发布时间】:2018-07-25 13:40:43
【问题描述】:
我正在尝试创建自己的 UserManager 扩展自原始版本,当我通过电子邮件进行搜索时,找不到用户。但是如果我从上下文中进行搜索,如果我找到了用户(参见Get 方法)。为了验证它是否真的很好实现,我重写了FindByEmailAsync 方法并且它确实被调用了,但我不知道为什么用户找不到它。一些帮助?谢谢!
public void ConfigureServices(IServiceCollection servicesCollection)
{
servicesCollection.AddDbContext<MyIndentityContext>(currentOptions =>
currentOptions.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
servicesCollection.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<MyIndentityContext>()
.AddRoleStore<ApplicationRoleStore>()
.AddUserStore<ApplicationUserStore>()
.AddUserManager<ApplicationUserManager>()
.AddRoleManager<ApplicationRoleManager>()
.AddSignInManager<ApplicationSignInManager>()
.AddDefaultTokenProviders();
...
...
...
}
public class MyIndentityContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
private readonly IConfiguration _configuration;
private readonly IHttpContextAccessor _httpContextAccessor;
public MyIndentityContext(DbContextOptions dbContextOptions, IHttpContextAccessor httpContextAccessor,
IConfiguration configuration)
: base(dbContextOptions)
{
_configuration = configuration;
_httpContextAccessor = httpContextAccessor;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("Sample.API");
}
}
public class ApplicationRoleManager : RoleManager<ApplicationRole>
{
public ApplicationRoleManager(IRoleStore<ApplicationRole> roleStore,
IEnumerable<IRoleValidator<ApplicationRole>> roleValidators, ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors, ILogger<ApplicationRoleManager> logger) : base(roleStore,
roleValidators,
keyNormalizer, errors, logger)
{
}
}
public class ApplicationSignInManager : SignInManager<ApplicationUser>
{
public ApplicationSignInManager(UserManager<ApplicationUser> userManager, IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory, IOptions<IdentityOptions> optionsAccessor,
ILogger<ApplicationSignInManager> logger, IAuthenticationSchemeProvider schemes) : base(userManager,
contextAccessor, claimsFactory, optionsAccessor, logger, schemes)
{
}
}
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> userStore, IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<ApplicationUser> passwordHasher,
IEnumerable<IUserValidator<ApplicationUser>> userValidators,
IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors, IServiceProvider services, ILogger<ApplicationUserManager> logger) :
base(userStore, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors,
services, logger)
{ }
// Custom implementation to check if you are really calling the method
public override Task<ApplicationUser> FindByEmailAsync(string email)
{
return Task.Run(() => new ApplicationUser
{
UserName = "A_NAME"
});
}
}
public class ApplicationRoleStore : RoleStore<ApplicationRole, MyIndentityContext>
{
public ApplicationRoleStore(MyIndentityContext dbContext, IdentityErrorDescriber identityErrorDescriber)
: base(dbContext, identityErrorDescriber)
{}
}
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, MyIndentityContext, string>
{
public ApplicationUserStore(MyIndentityContext dbContext, IdentityErrorDescriber identityErrorDescriber)
: base(dbContext, identityErrorDescriber)
{}
}
public class ApplicationUser : IdentityUser {}
public class ApplicationRole : IdentityRole
{
public ApplicationRole() { }
public ApplicationRole(string roleName) : base(roleName) { }
public ApplicationRole(string roleName, string roleDescription) : base(roleName)
{
Description = roleDescription;
}
}
[Authorize]
[ApiController]
[Route("api/[controller]")]
[EnableCors(CORS.AllowSpecificOrigins)]
public class UserController : BaseController
{
private readonly ApplicationUserManager _applicationUserManager;
public UserController(ApplicationUserManager applicationUserManager)
{
_applicationUserManager = applicationUserManager;
}
// GET: api/User/5
[HttpGet("{id}")]
public async Task<UserDTO> Get(int id)
{
var currentUser = await _applicationUserManager.FindByEmailAsync("example@example.com"); ==> RETURN NULL!
var otherUser = _indentityContext.Users.Where(x => x.Email == "example@example.com"); ==> RETURN CORRECT USER!
return currentUser;
}
}
【问题讨论】:
-
如果您还没有看过Custom storage providers for ASP.NET Core Identity,那可能会给您一些建议。
-
return Task.Run(...)永远不会工作。我认为这只是示例代码,但请尝试return Task.FromResult(new ApplicationUser { UserName = "A_NAME" });让它工作。 -
你能和我们分享一个项目吗?我用你当前的代码做了一个测试,它工作正常。您是否使用多个
DbContext?您是否通过Task.Run(() => new ApplicationUser { UserName = "A_NAME" });获得用户? -
@Edward 嗨!我只使用一个上下文。我添加了 Task.Run 以验证 FindByEmailAsync 方法是否实际被调用。这将返回一个名为“A_NAME”的用户。后来我留下了一个带有代码的github链接。
-
@Edward 检查存储库。 github.com/avechuche/Sample.API.git
标签: c# asp.net-core asp.net-core-2.1 asp.net-core-identity