I seem to have a hate/love relation with the Identity. I love it because it is a complete solution for most applications. But I hate it because extending is not an easy task. I feel it is more complected than it should be.
I am trying to add custom attributes and foreign keys to my user model but it seems to be a very difficult task.
I need to add a new Identity
field called UserId
since Id is a string which will be auto generated by the database. Then, I need to add a foreign key to Company
model and another one to Location
model.
I followed the instruction in the answer from this other question in an attempt to add two new foreign keys and be able to get their value from my controllers.
Here is what I have done so far. My ApplicationUser
class after the modifications I made look like this
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;
}
}
I also created an extensions class that allows me to get the values from the controllers like so
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;
}
}
But I am running into the error "listed below" when I try to add a new migration
Here is the error
One or more validation errors were detected during model generation:
ApplicationUser_Claims_Source_ApplicationUser_Claims_Target: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'MyUserId' on entity 'IdentityUserClaim' does not match the type of property 'MyUserId' on entity 'ApplicationUser' in the referential constraint 'ApplicationUser_Claims'. ApplicationUser_Logins_Source_ApplicationUser_Logins_Target: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'MyUserId' on entity 'IdentityUserLogin' does not match the type of property 'MyUserId' on entity 'ApplicationUser' in the referential constraint 'ApplicationUser_Logins'. ApplicationUser_Roles_Source_ApplicationUser_Roles_Target: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'MyUserId' on entity 'IdentityUserRole' does not match the type of property 'MyUserId' on entity 'ApplicationUser' in the referential constraint 'ApplicationUser_Roles'.
This is the command I used to created the InitialCreate
migration
Add-Migration InitialCreate
How can I add my foreign key and be able to get them from the controllers correctly?