How to get user information in DbContext using Net Core

.net-core, asp.net-core, c#, entity-framework-core

Solution

I implemented an approach similar to this that is covered in this blog post and basically involves creating a service that will use dependency injection to inject the `HttpContext` (and underlying user information) into a particular context, or however you would prefer to use it.

A very basic implementation might look something like this:

public class UserResolverService  
{
    private readonly IHttpContextAccessor _context;
    public UserResolverService(IHttpContextAccessor context)
    {
        _context = context;
    }

    public string GetUser()
    {
       return _context.HttpContext.User?.Identity?.Name;
    }
}

You would just need to inject this into the pipeline within the `ConfigureServices` method in your `Startup.cs` file :

services.AddTransient<UserResolverService>();

And then finally, just access it within the constructor of your specified `DbContext` :

public partial class ExampleContext : IExampleContext
{
    private YourContext _context;
    private string _user;
    public ExampleContext(YourContext context, UserResolverService userService)
    {
        _context = context;
        _user = userService.GetUser();
    }
}

Then you should be able to use `_user` to reference the current user within your context. This can easily be extended to store / access any content available within the current request as well.

Problem

I am trying to develop a class library in which i want to implement custom `DbContext`. In the `SaveChanges` method of the `DbContext`, i need to get current user’s information(department, username etc.) for auditing purpose. Some part of the `DbContext` code is below: ``` public override int SaveChanges() { // find all changed entities which is ICreateAuditedEntity var addedAuditedEntities = ChangeTracker.Entries<ICreateAuditedEntity>() .Where(p => p.State == EntityState.Added) .Select(p => p.Entity); var now = DateTime.Now; foreach (var added in addedAuditedEntities) { added.CreatedAt = now; added.CreatedBy = ?; added.CreatedByDepartment = ? } return base.SaveChanges(); } ``` Two options coming to mind: - Using `HttpContext.Items` to keep user information, injecting IHttpContextAccessor and getting information from the `HttpContext.Items`(In this case `DbContext` depends `HttpContext`, is it correct?) - Using ThreadStatic object instead of `HttpContext.Items` and getting information from the object( I read some posts that ThreadStatic is not safe) Question : Which is the best fit into my case? Is there another way you suggest?

Original source

Related problems