【发布时间】:2017-07-24 04:38:07
【问题描述】:
我正在尝试使用不带 EntityFramework 但具有整数 ID(UserId 和 RoleId)的 Identity 创建一个 .net Core 解决方案。我已经按照这个基本设置来创建解决方案和删除 EF (https://taherchhabra.github.io/jekyll/update/2016/09/22/aspnet-core-identity-without-entityframework.html),但这仍然有用户的愚蠢 Guid id 列。当我尝试更改它时,我在创建 UserStore 时遇到了问题,因为它继承自 IUserStore<User>,这需要我实现
Task<User> FindByIdAsync(string userId, CancellationToken cancellationToken)
这或当然意味着 Id 值是一个字符串而不是一个 int。
我已经阅读了几篇关于如何将基于 EF 的解决方案更改为使用整数的文章,并且我深入研究了 EF 是如何做到这一点的,但它都是基于使用 TKey 的 EF 类。
我尝试创建自己的 IUserStore 以将字符串更改为整数,但项目甚至无法启动(它可以正常编译,但是当我尝试在本地运行它时,它会在完成启动之前退出)。
有谁知道如何做到这一点?找了好久都没找到。
编辑: 到目前为止,我所做的是创建自己的 UserStore 和 RollStore(它们基本上只是原件的副本,一旦我开始工作,我将对其进行调整)。在我的 HomeController 中,我添加了以下内容:
public class HomeController : Controller
{
private readonly UserManager<models.User> _userManager;
public HomeController(UserManager<models.User> userManager)
{
_userManager = userManager;
}
public async Task<IActionResult> Index()
{
var user = new models.User();
if(User.Identity.IsAuthenticated)
user = await _userManager.FindByNameAsync(User.Identity.Name);
return View();
}
}
这基本上是一个“是否已插入”测试,我可以在调试器中逐步完成。
在我的Startup.cs:
services.AddSingleton<IUserStore<User>, UserStore>();
services.AddSingleton<IRoleStore<Role>, RoleStore>();
services.AddIdentity<User, Role>()
.AddDefaultTokenProviders();
这实际上会起作用(通过我的端点进行调试,user 已正确填充)。但是,如果我仔细观察,我会发现 IUserStore 和 IRoleStore 是 Microsoft.AspNetCore.Identity 版本,这意味着我仍然依赖于这些合同,并且需要使用 Guid 作为 Id。
如果我强制解决问题,请使用
services.AddSingleton<SandboxCoreDapper.Identity.Interfaces.IUserStore<User>, UserStore>();
services.AddSingleton<SandboxCoreDapper.Identity.Interfaces.IRoleStore<Role>, RoleStore>();
然后当我尝试访问我的端点时,UserManager 将无法解析:
“无法解析类型 'Microsoft.AspNetCore.Identity.IUserStore1[SandboxCoreDapper.Models.User]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager1[SandboxCoreDapper.Models.User]' 的服务。”
编辑 2 我发现了这个有趣的讨论:https://github.com/aspnet/Identity/issues/493
基于此,我继续创建了自己的 RoleManager 和 UserManager,它们基本上只是扩展了身份版本:
namespace SandboxCoreDapper.Identity.Services
{
public class UserManager<TUser> : Microsoft.AspNetCore.Identity.UserManager<TUser> where TUser : class
{
public UserManager(
sandyId.IUserStore<TUser> store, // my version of IUserStore
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<TUser> passwordHasher,
IEnumerable<IUserValidator<TUser>> userValidators,
IEnumerable<IPasswordValidator<TUser>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<UserManager<TUser>> logger)
:base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
{
}
}
}
RoleManager 也是如此。
然后我添加到Startup.cs
services.AddIdentity<User, Role>()
.AddDefaultTokenProviders()
.AddUserManager<SandboxCoreDapper.Identity.Services.UserManager<User>>()
.AddRoleManager<SandboxCoreDapper.Identity.Services.RoleManager<Role>>()
;
到目前为止一切都很好......
【问题讨论】:
-
谢谢@ganders。我已经阅读了这个问题,但我坚持“如果你实现了用户存储和角色存储,你可以使用内置的 UserManager,除非你有其他理由这样做,否则不需要自己实现。”我正在尝试这样做,但
UserManager一直指向默认标识UserStore,我不知道如何将其指向我自己的版本。我能找到的关于这个主题的唯一文章是关于 Identity 2 --pre Core -
您是否在 startup.cs 文件中注册了您的 UserStore?