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