-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
UserManager.AddToRoleAsync() will throw InvalidOperationException with message: The instance of entity type 'IdentityUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked..
All packages versioned 9.0.8.
Expected Behavior
Success to add user to role.
Steps To Reproduce
- Create an ASP.NET Core Razor pages application with Identity.
- Add
RoleManager
and api controllers to application. EditProgram.Main()
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>() // add this line
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddMvc(); // replace razor pages to mvc
app.MapControllers(); // map api controller
- Add controller to call
AddToRoleAsync()
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[HttpGet(nameof(AddRole))]
public async Task<IActionResult> AddRole()
{
var roleManager = HttpContext.RequestServices.GetRequiredService<RoleManager<IdentityRole>>();
if(!await roleManager.RoleExistsAsync("test"))
{
await roleManager.CreateAsync(new() { Name = "test" });
}
return Ok();
}
[HttpGet(nameof(AddToRole))]
public async Task<IActionResult> AddToRole()
{
var requestProvider = HttpContext.RequestServices;
IdentityUser? user = null;
IdentityRole? role = null;
await using (var scope = requestProvider.CreateAsyncScope())
{
var provider = scope.ServiceProvider;
var userManager = provider.GetRequiredService<UserManager<IdentityUser>>();
var roleManager = provider.GetRequiredService<RoleManager<IdentityRole>>();
user = await userManager.FindByNameAsync("[email protected]");
role = await roleManager.FindByNameAsync("test");
}
if (user != null && role != null)
{
// Use new scope to ensure not tracked.
await using var scope = requestProvider.CreateAsyncScope();
var provider = scope.ServiceProvider;
var userManager = provider.GetRequiredService<UserManager<IdentityUser>>();
var res = await userManager.AddToRoleAsync(user, role.Name!);
}
return Ok();
}
}
- Register user named "[email protected]" using web page.
- Access endpoint "/api/test/addrole" to add role named "test".
- Access endpoint "/api/test/addtorole" to call
AddToRoleAsync()
.
Exceptions (if any)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The instance of entity type 'IdentityUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap1.ThrowIdentityConflict(InternalEntityEntry entry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap
1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap1.Add(TKey key, InternalEntityEntry entry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NullableKeyIdentityMap
1.Add(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable1 forceStateWhenUnknownKey, Nullable
1 fallbackState)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode1 node) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode
1 node, Func2 handleNode) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey) at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState) at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState) at Microsoft.EntityFrameworkCore.DbContext.Attach[TEntity](TEntity entity) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore
9.UpdateAsync(TUser user, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Identity.UserManager1.UpdateUserAsync(TUser user) at Microsoft.AspNetCore.Identity.UserManager
1.AddToRoleAsync(TUser user, String role)
at TestUserRole.Controllers.TestController.AddToRole() in F:\source\repos\TestUserRole\TestUserRole\Controllers\TestController.cs:line 45
at TestUserRole.Controllers.TestController.AddToRole() in F:\source\repos\TestUserRole\TestUserRole\Controllers\TestController.cs:line 45
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
.NET Version
9.0.8
Anything else?
No response