Entity Tracking Conflict when Authenticating Users in ASP.NET Core API

44 Views Asked by At

I'm working on an ASP.NET Core API for user authentication, and I'm encountering an issue regarding entity tracking conflict. Here's a breakdown of my setup:

I have a method called Token in my AccountController responsible for handling user authentication. Within this method, I call another method named CheckUserWithPassword to authenticate the user.

[HttpPost]
[Route("/api/login")]
[Consumes("application/json")]
public async Task<IActionResult> Token(LoginDto postModel)
{
    var userResult = await CheckUserWithPassword(postModel);
    // Rest of the implementation
}

private async Task<int> CheckUserWithPassword(LoginDto model)
{
    
            var user = await _userService.GetUser(model.Username);
            if (user == null)
                throw new ClientSideException("Kullanıcı Bulunamadı");

            if (!user.IsActive)
                throw new ClientSideException("Kullanıcı aktif değil.");

            try
            {
                byte[] bytes = Convert.FromBase64String(model.Password);
                var passClean = Encoding.ASCII.GetString(bytes);
                var result = await _signInManager.CheckPasswordSignInAsync(user, passClean, false);
}

The CheckUserWithPassword method retrieves the user using _userService.GetUser(model.Username). Here's the implementation of GetUser method:

public async Task<AppUser> GetUser(string userName)
{
    return await _context.AppUsers
            .Include(u => u.Client)
            .Where(u => u.Email == userName)
            .AsNoTracking()
            .FirstOrDefaultAsync();
}

The GetUser method is defined in the IAppUserService interface and implemented in the AppUserService class.

public interface IAppUserService : IService<AppUser>
{
    Task<AppUser> GetUser(string userName);
}

public class AppUserService : Service<AppUser>, IAppUserService
{
    // Implementation details
}

public class RepoServiceModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IGenericRepository<>)).InstancePerLifetimeScope();
        builder.RegisterGeneric(typeof(Service<>)).As(typeof(IService<>)).InstancePerLifetimeScope();
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();

        var apiAssembly = Assembly.GetExecutingAssembly();
        var repoAssembly = Assembly.GetAssembly(typeof(AppDbContext));
        var serviceAssembly = Assembly.GetAssembly(typeof(MappingProfile));

        builder.RegisterAssemblyTypes(apiAssembly, repoAssembly, serviceAssembly).Where(x => x.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerLifetimeScope();
        builder.RegisterAssemblyTypes(apiAssembly, repoAssembly, serviceAssembly).Where(x => x.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
    }
}

// Inside Program.cs
builder.Services.AddScoped<DbContext,AppDbContext>();
builder.Services.AddFluentValidationAutoValidation();

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder => containerBuilder.RegisterModule(new RepoServiceModule()));


However, when attempting to authenticate a user, I encounter the following error:

"The instance of entity type 'AppUser' 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."

It seems like the conflict arises when attempting to track multiple instances of AppUser. How can I resolve this issue to successfully authenticate users without encountering this tracking conflict? Any insights or suggestions would be greatly appreciated. Thank you!

0

There are 0 best solutions below