如何自定义ASP.NET Identity以处理应用程序范围内的用户?

时间:2014-11-07 22:06:49

标签: asp.net-mvc entity-framework entity-framework-6 asp.net-identity asp.net-identity-2

我正在开发一个应用程序,用于记录注册访问网页上某些资源的用户。我使用带有ASP.NET身份的ASP.NET MVC 5。我对Email和UserName使用相同的值。我有一个存储网页的表。我还在AspNetUsers表中添加了一个WebpageId列来标识网页。实际上,在AspNetUsers表和网页表之间有很多关系,但出于某种原因,我想在AspNetUsers表中为用户创建多条记录 - 每个用户注册的网页都有一条记录。

如果具有user@examplemail.com的用户注册到网页1,则并不意味着他已注册到网页2。当他使用相同的电子邮件注册到网页2时,对他来说实际上完全不可见,他已经作为网页1的用户在系统中注册。

为了在AspNetUsers表中拥有多个具有相同UserName的记录,我删除了UserName上的唯一索引,而是我在两列上创建了一个唯一索引:UserName和WebpageId。

但是当我尝试使用已经注册到网页1的电子邮件地址注册到网页2时,我得到 DbEntityValidationException ,并带有以下验证消息:“用户名用户@ examplemail.com 已被采纳“。当UserManger用于创建新用户时,会在AccountControler.Register()方法中抛出此内容。

我第一次尝试解决问题的方法是自定义UserManager 类。我创建了一个UserManager的子类,我以一种他们寻找一对电子邮件+网页或名称+网页的方式覆盖 FindByEmailAsync FindByNameAsync 方法:

var existingUser = this.db.Users
                  .FirstOrDefault(x => x.UserName == userName && 
                                       x.WebpageId == webpageId);
return existingUser;

我的第二次尝试是另外自定义此UserManager的UserValidator 。我在那里做了类似于上面的代码 - 尝试让用户具有相同的UserName和webpageId。找不到用户时,我返回IdentityResult.Success。

没有成功。仍然出现DbEntityValidationException并显示“Username user@examplemail.com已经采取”验证错误。

知道哪个ASP.NET Identity组件仍然在寻找具有用户名的用户(不检查webpageId)?我应该如何自定义ASP.NET身份来处理这种情况?

以下是异常callstack的一部分:

  

at System.Data.Entity.Internal.InternalContext.SaveChangesAsync(CancellationToken cancellationToken)   在System.Data.Entity.Internal.LazyInternalContext.SaveChangesAsync(CancellationToken cancellationToken)   在System.Data.Entity.DbContext.SaveChangesAsync(CancellationToken cancellationToken)   在System.Data.Entity.DbContext.SaveChangesAsync()   在Microsoft.AspNet.Identity.EntityFramework.UserStore 6.<SaveChanges>d__31.MoveNext() (...) at System.Runtime.CompilerServices.TaskAwaiter 1.GetResult()   at UserRegistrationSystem.Web.Controllers.AccountController.d__11.MoveNext()in i:\ Repo \ RegistrationSystem \ UserRegistrationSystem.Web \ Controllers \ AccountController.cs:第126行

仅供参考,我也在ASP.NET Identity forum上提出了同样的问题。

1 个答案:

答案 0 :(得分:0)

您所描述的内容听起来像多租户。

我已经回答了相关问题here,并提供了一个库来实现它

https://github.com/JSkimming/AspNet.Identity.EntityFramework.Multitenant