Customize the primary key data type for Identity in asp.net core 2 creates problems in UserStore - asp.net-core

I need the primary key for my user class in Identity to be long instead of the default string. Following this MS tutorial. So i do all that (just replace GUID in the tutorial with long) and everything was looking good until I was working on created a seed class
var userStore = new UserStore<ApplicationUser>(context);
gives me the squiggles on ApplicationUser with the message:
Error CS0311 The type 'WSCPA_AC.Models.ApplicationUser' cannot be used as type parameter 'TUser' in the generic type or method 'UserStore'. There is no implicit reference conversion from 'WSCPA_AC.Models.ApplicationUser' to 'Microsoft.AspNetCore.Identity.IdentityUser'.
Now I see mention of this sort of problem in the comments at the bottom of the tutorial. Do I have to somehow override the UserStore class, and if so, how?

I think you will need to use the base class of UserStore which has a signature of UserStore<TUser, TRole, TContext, TKey> as follows:
var userStore = new UserStore<ApplicationUser, IdentityRole<long>, TContext, long>(context);
Where TContext is the type of your database context.

Related

Error when creating token with laravel Santum

I am having problems when generating tokens with laravel sanctum.
The error claims that the value is out of range for the column 'tokenable_id'.
Here textual: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'c247a941-4954-4bf3-91eb-ddf37a8e2611' for column 'tokenable_id'.
This is the error message (image)
In my user model, I have implemented the uuid as the primary key, so the id corresponds to this code: c247a941-4954-4bf3-91eb-ddf37a8e2611, which claims the error.
This is the function where I am creating the token
LoginController.php
class LoginController extends Controller
{
public function __invoke(Request $request)
{
$user = User::whereEmail($request->email)->first();
/* Token generation */
$plainTextToken = $user->createToken($request->device_name)->plainTextToken;
return response()->json([[
'plain-text-token' => $plainTextToken
]);
}
}
To my understanding, this uuid, is the one that is generating me the error, then , my question goes to what action should I implement to resoolver with uuid with primary key.
Should I modify the personal tokens table, so that it accepts this string that is now the user id?
I remain attentive to any suggestion.
Remember to update your personal_access_tokens table migration. Change morphs('tokenable') to uuidMorphs('tokenable'), since morphs() is used when your related model (users in this case) uses auto increment. Since you are using uuids, you have to make this change to support those values.

Change column name for non-primitive field (navigation) with EF Core

Given the following classes:
public class Mission
{
private MissionCard _missionCard;
}
public class MissionCard
{
}
I would like to create this relationship via Fluent API so that _missionCard is treated as a relationship and can be populated from DB but isn't available as a property on my Mission model.
I can create that relationship with:
modelBuilder.Entity<Mission>().HasOne<MissionCard>("_missionCard");
but by default this creates a FK column named "_missionCard". The docs show that a custom name can be specified when using .Property("property name").FromField("field name") but you cannot use .Property for non-primitive types.
Is it possible to change the column name for a relationship like above?
Managed to resolve this by inverting the relationship:
modelBuilder.Entity<MissionCard>()
.HasMany<Mission>()
.WithOne("_missionCard")
.HasForeignKey(nameof(MissionCard));

Include operator could not be bound in Entity Framework Core with Identity DB

I am writing a application using ASP.Net Core + EF Core + Identity 2.0 + DB First + Repository Pattern
From DB first I am scaffolding an existing database (with Identity tables) and do some clean up steps in Context to make it work for Identity.
Inherit it from IdentityDbContext instead of DbContext
public partial class SampleDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
Remove "OnConfiguring" method override
Add a new constructor for the SampleDbContext class public SampleDbContext (DbContextOptions<SampleDbContext> options):base(options){}
Remove all DbSet configuration for EF Core Identity tables such as,
AspNetRoleClaims
AspNetRoles
AspNetUserClaims
AspNetUserLogins
AspNetUserRoles
AspNetUserTokens
AspNetUsers
In "OnModelCreating" override function add below line base.OnModelCreating(modelBuilder);
Remove all modelBuilder.Entity configs for all EF Core Identity tables mentioned above.
Add below line in OnModelCreating() function,
modelBuilder.Entity<AspNetUserLogins>().HasKey(i => i.LoginProvider);
modelBuilder.Entity<AspNetUserLogins>().HasKey(i => i.ProviderKey);
modelBuilder.Entity<AspNetUserRoles>().HasKey(i => i.UserId);
modelBuilder.Entity<AspNetUserRoles>().HasKey(i => i.RoleId);
modelBuilder.Ignore<AspNetRoleClaims>();
modelBuilder.Ignore<AspNetRoles>();
modelBuilder.Ignore<AspNetUserClaims>();
modelBuilder.Ignore<AspNetUserLogins>();
modelBuilder.Ignore<AspNetUserRoles>();
modelBuilder.Ignore<AspNetUsers>();
So far all works fine. Able to read/write data to DB.
Now, attempting to read a table data which has a foreign key reference to one of Identity tables (ASPNetUsers) as follows,
var dbEntries = await _addressRepository.GetAllAsync(x => x.CreatedBy);
where CreatedBy is foreign key reference to "Id" columns in AspNetUsers table passed as include property to my repository.
Now the above GetAll() command throws exception,
InvalidOperationException: The expression '[x].CreatedBy' passed to the Include operator could not be bound.
Could any one help me to resolve this issue? I spent over a day to find solution online, but nothing got.
Additional Note: All are working fine if I refer my own tables in Include objects. Issue only with Identity tables.
Thanks in advance.

TenantId is null when saving an entity in a Discriminator based multi tenant application in Grails 3.2 with GORM 6

I am trying to implement a MultiTenant application using GORM 6.0.0.RC2.
When a domain class that implements MultiTenant is saved via the GORM's save() method, the tenantId property is not set to the current tenantId. It is always null and hence fails validation. However Tenants.currentId() returns the correct tenant id based on the specified tenant resolver class.
Is it the application's responsibility to set the tenantId on an instance of the domain class when it is saved or will GORM take care of it by setting the property appropriately before being saved?
My Domain Person class
class Person implements MultiTenant<Person> {
String id
String tenantId
String name
}
and the code to save an instance of the Person class is
new Person(name: "pmohan").save(failOnError: true)
it always fails with a validation exception indicating tenantId is null.
But the tenant resolver according to the configuration below resolves to the right tenantId.
gorm:
multiTenancy:
mode: DISCRIMINATOR
tenantResolverClass: com.MyTenantResolver
Also the Tenants.currentId returns the value as expected. I was expecting the save() method to populate the tenantId property automatically based on MyTenantResolver class.

How to get Doctrine2 entity identifier without knowing its name

I am attempting to create an abstracted getId method on my base Entity class in Symfony2 using Doctrine2 for a database where primary keys are named inconsistently across tables.
When inspecting entity objects I see there is a private '_identifier' property that contains the information I am trying to retrieve but I am not sure how to properly access it.
I'm assuming there is some simple Doctrine magic similar to:
public function getId()
{
return $this->getIdentifier();
}
But I haven't managed to find it on the intertubes anywhere.
You can access this information via EntityManager#getClassMetadata(). An example would look like this:
// $em instanceof EntityManager
$meta = $em->getClassMetadata(get_class($entity));
$identifier = $meta->getSingleIdentifierFieldName();
If your entity has a composite primary key, you'll need to use $meta->getIdentifierFieldNames() instead. Of course, using this method, you'll need access to an instance of EntityManager, so this code is usually placed in a custom repository rather than in the entity itself.
Hope that helps.