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?