As a part of logging who entered/updated the data I am adding 4 common fields (Created By, Created Date, Modified By, Modified Date) in all entities. For this, I am using shadow properties feature suggested in multiple forums including https://dotnetcore.gaprogman.com/2017/01/26/entity-framework-core-shadow-properties/
My question is how do I get information about authenticated user ?. If it was a controller I could access ApplicationUserManager but in this case the shadow properties are in
AppDbContext : IdentityDbContext class.
This is a asp.net core 2 web API project.
Any suggestion is highly appreciated. Thanks
You can get the current user's name using HttpContext.User.Identity.Name. You can access the HttpContext using IHttpContextAccessor. This interface should already be registered in the service collection. Otherwise, you can register it:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// ...
}
Then, you can use this interface from the DbContext:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor;
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
var httpContext = _httpContextAccessor.HttpContext;
if(httpContext != null)
{
var authenticatedUserName = httpContext.User.Identity.Name;
// If it returns null, even when the user was authenticated, you may try to get the value of a specific claim
var authenticatedUserId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value
// var authenticatedUserId = _httpContextAccessor.HttpContext.User.FindFirst("sub").Value
// TODO use name to set the shadow property value like in the following post: https://www.meziantou.net/2017/07/03/entity-framework-core-generate-tracking-columns
}
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With