1

Working implementation I have changed the default type of the identityUser to an integer and the rest of the configuration in order to get it to work correctly again.

Startup Configuration

Changed: identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(IdentityRole<int>), identityBuilder.Services);

Custom User class

Changed: public class AppUser : IdentityUser<int>

ApplicationDbContext

Changed:  public class ApplicationDbContext : IdentityDbContext<AppUser, IdentityRole<int>, int, IdentityUserClaim<int>, IdentityUserRole<int>, IdentityUserLogin<int>,IdentityRoleClaim<int>, IdentityUserToken<int>>

Old Implementation The identityResult variable in the Repository implementation is returning null and throws the following exception:

System.InvalidOperationException: Unable to track an entity of type 'AppUser' because primary key property 'Id' is null

Startup Configuration

var identityBuilder = services.AddIdentityCore<AppUser>(o =>
    {
        // configure identity options
        // Options are intentionally let out
    });

identityBuilder = new IdentityBuilder(identityBuilder.UserType, typeof(IdentityRole), identityBuilder.Services);
identityBuilder.AddEntityFrameworkStores<ApplicationDbContext>();

Custom User class

public class AppUser : IdentityUser 
{
    // Extended Properties
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

ApplicationDbContext

public class ApplicationDbContext : IdentityDbContext<AppUser>

Repository

public async Task<CreateUserResponse> CreateUser(User user, string password)
{
    var appUser = _mapper.Map<AppUser>(user);           
    var identityResult = await _userManager.CreateAsync(appUser, password);         
    return new CreateUserResponse(appUser.Id.ToString(), identityResult.Succeeded, identityResult.Succeeded ? null : identityResult.Errors.Select(e => new Error(e.Code, e.Description)));
}   
  • The question isn't clear and using a templated layout won't make it clearer. The *relevant* parts are that you use `UserManager` with an `AppUser` class whose `Id` is *nullable*. That's strange to say the least. The correct type for a Guid is Guid in C# and `UNIQUEIDENTIFIER` in the database. You didn't post any code though so one can only guess what's going on. Post the code that raised the error, the DbContext configuration and the code for AppUser. My guess would be that the Id to wasn't set to a a new Guid, eg with `Guid.NewGuid()` – Panagiotis Kanavos Oct 03 '19 at 12:02
  • In any case a Guid is a *very bad choice* for a primary key as the generated values are too big, they aren't in order and end up causing constant table fragmentation. At the very least you should mark the Id as database-generated and use the [NEWSEQUENTIALID()](https://learn.microsoft.com/en-us/sql/t-sql/functions/newsequentialid-transact-sql?view=sql-server-2017) method as the default value for the field in the database. Or use a more appropriate type like `int` or `long` if you expect so many users – Panagiotis Kanavos Oct 03 '19 at 12:05
  • Hello Panagiotis Kanavos, Thanks for pointing me in the right direction and the advice to post the code. I will do that next time so it is clear what I currently have build. After looking into the default implementation in which they use the string. I have changed everything to int. This now works correctly. For some reason the default implementation seems to be broken. – Roy Mengelers Oct 03 '19 at 12:52
  • If that were the case thousands of developers would have noticed already and *no* project would work without modifications - the default `IdentityUser` uses `string` which means all projects using the default Identity classes would fail – Panagiotis Kanavos Oct 03 '19 at 12:55
  • 1
    Hello Panagiotis Kanavos, You are correct that this would be strange. Since I am still not seeing this issue pop-up for others. Lets then put it this way: I assumed that this would be the problem. But maybe the problem is somewhere else. The weird thing is that the same code worked in .NetCore 2.2 where I was using the default. So that was why I assumed it. But ofcourse this could have something to do with some of the changes that I had to do to convert the project from 2.2 to version 3.0. Once again thanks for your feedback. – Roy Mengelers Oct 03 '19 at 13:06
  • I had same issue and I fix this in mapping part like this: ```CreateMap(MemberList.Source).ForMember(dest => dest.Id, opt => opt.Condition(srs => srs.Id != null));``` - If `Id` on `UserDto` is `null`, then I use default value from `UserIdentity` - which is automatically generated `Guid`. This is becuase of this breaking change: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#string-and-byte-array-keys-are-not-client-generated-by-default – Jenan Nov 06 '19 at 16:53
  • In the future, please post your solution as an answer, instead of updating your question with the implementation that worked for you. (Yes, you are allowed to answer your own question, and the practice is perfectly acceptable.) Like @PanagiotisKanavos, I am skeptical that the issue was due to the OOTB template using a string, but by posting your solution as an answer it allows the community to evaluate that independent of your original problem. – Jeremy Caney Apr 04 '20 at 02:38

0 Answers0