我似乎与身份有仇恨/爱情关系。我喜欢它,因为它是大多数应用程序的完整解决方案。但我讨厌它,因为延伸并不是一件容易的事。我觉得它比它应该更加复杂。
我正在尝试向我的用户模型添加自定义属性和外键,但这似乎是一项非常困难的任务。
我需要添加一个名为Identity
的新UserId
字段,因为Id是一个字符串,将由数据库自动生成。然后,我需要将一个外键添加到Company
模型,将另一个外键添加到Location
模型。
我按照answer from this other question中的说明尝试添加两个新的外键,并能够从我的控制器中获取它们的值。
这是我到目前为止所做的。我做出修改后的ApplicationUser
课程看起来像这样
public class ApplicationUser : IdentityUser
{
[Key]
public int MyUserId { get; set; }
[ForeignKey("Company")]
public int CompanyId { get; set; }
[ForeignKey("Location")]
public int CurrentLocationId { get; set; }
public virtual Company Company { get; set; }
public virtual Location Location { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity.AddClaim(new Claim("MyUserId", this.MyUserId.ToString() ));
userIdentity.AddClaim(new Claim("CompanyId", this.CompanyId.ToString() ));
userIdentity.AddClaim(new Claim("CurrentLocationId", this.CurrentLocationId.ToString()));
return userIdentity;
}
}
我还创建了一个扩展类,允许我从控制器中获取值,如此
public static class IdentityExtensions
{
public static int GetComapnyId(this IIdentity identity)
{
var claim = ((ClaimsIdentity)identity).FindFirst("ComapnyId");
// Test for null to avoid issues during local testing
return (claim != null) ? Int32.Parse(claim.Value) : 0;
}
public static int GetCurrentLocationId(this IIdentity identity)
{
var claim = ((ClaimsIdentity)identity).FindFirst("CurrentLocationId");
// Test for null to avoid issues during local testing
return (claim != null) ? Int32.Parse(claim.Value) : 0;
}
public static int GetMyUserId(this IIdentity identity)
{
var claim = ((ClaimsIdentity)identity).FindFirst("MyUserId");
// Test for null to avoid issues during local testing
return (claim != null) ? Int32.Parse(claim.Value) : 0;
}
}
但是我遇到了下面列出的错误&#34;&#34;当我尝试添加新的迁移
时这是错误
在模型生成期间检测到一个或多个验证错误:
ApplicationUser_Claims_Source_ApplicationUser_Claims_Target :: 参照的从属角色中的所有属性的类型 约束必须与相应的属性类型相同 主要角色。财产的类型&#39; MyUserId&#39;在实体上 &#39; IdentityUserClaim&#39;不符合财产的类型&#39; MyUserId&#39;上 实体&#39; ApplicationUser&#39;在引用约束中 &#39; ApplicationUser_Claims&#39 ;. ApplicationUser_Logins_Source_ApplicationUser_Logins_Target :: 参照的从属角色中的所有属性的类型 约束必须与相应的属性类型相同 主要角色。财产的类型&#39; MyUserId&#39;在实体上 &#39; IdentityUserLogin&#39;不符合财产的类型&#39; MyUserId&#39;上 实体&#39; ApplicationUser&#39;在引用约束中 &#39; ApplicationUser_Logins&#39 ;. ApplicationUser_Roles_Source_ApplicationUser_Roles_Target ::类型 参照约束的从属角色中的所有属性 必须与Principal中的相应属性类型相同 角色。财产的类型&#39; MyUserId&#39;实体&#39; IdentityUserRole&#39;不 不符合财产的类型&#39; MyUserId&#39;在实体&#39; ApplicationUser&#39;在 引用约束&#39; ApplicationUser_Roles&#39;。
这是我用来创建InitialCreate
迁移
Add-Migration InitialCreate
如何添加外键并能够正确地从控制器获取外键?
答案 0 :(得分:0)
Identity可以将主键(Id字段)更改为int
。这是很多样板/空类,但它适用于我们。也许这会有所帮助?
public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
[ForeignKey("Company")]
public int CompanyId { get; set; }
[ForeignKey("Location")]
public int CurrentLocationId { get; set; }
public virtual Company Company { get; set; }
public virtual Location Location { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity.AddClaim(new Claim("CompanyId", this.CompanyId.ToString() ));
userIdentity.AddClaim(new Claim("CurrentLocationId", this.CurrentLocationId.ToString()));
return userIdentity;
}
}
public class ApplicationUserLogin : IdentityUserLogin<int>
{
}
public class ApplicationUserRole : IdentityUserRole<int>
{
[ForeignKey("RoleId")]
public virtual ApplicationRole Role { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; }
}
public class ApplicationRole : IdentityRole<int, UserRole>
{
}
public class ApplicationUserClaim : IdentityUserClaim<int>
{
}
然后我们还需要自定义ApplicationUserStore
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
public ApplicationUserStore(DbContext context)
: base(context)
{
}
}