ASP.NET Core 2.2 在 DbContext 中获取 userId
ASP.NET Core 2.2 get userId in DbContext
我对 ASP.NET Core 还很陌生。
我想创建 ASP.NET Core 2.2 WebAPI,具有 Entity Framework Core 和 ASP.NET Identity。
另外,我想使用 JWT 通过令牌来保护对 WebAPI 的访问。
我已成功将用户插入数据库并从我的 API 取回令牌,并且令牌身份验证正在运行。
但是,我还想软删除数据库记录并跟踪谁拥有 deleted/updated/added 记录。
测试 table 是国家,其中字段只有 Title
和 Description
.
到目前为止,我已经颠倒了互联网,但没有帮助:(
我试过的最后一件事是(userId 是 null
):
在startup.cs:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在我的 AppDbContext.cs
public class AppDbContext : IdentityDbContext<AppUser>{
public AppDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<AppUser> AppUsers { get; set; }
public DbSet<Country> Countries { get; set; } // just for testing
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// TODO - IGNORE THIS
//builder.Entity<AppUser>().Property<bool>("IsDeleted");
//builder.Entity<AppUser>().HasQueryFilter(m => EF.Property<bool>(m, "IsDeleted") == false);
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
CheckBeforeSaving();
return (await base.SaveChangesAsync(true, cancellationToken).ConfigureAwait(false));
}
private void CheckBeforeSaving()
{
var httpContextAccessor = this.GetService<IHttpContextAccessor>();
var userId = httpContextAccessor?.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
foreach (var entry in ChangeTracker.Entries())
{
switch (entry.State)
{
case EntityState.Detached:
break;
case EntityState.Unchanged:
break;
case EntityState.Deleted:
entry.State = EntityState.Modified;
entry.CurrentValues["IsDeleted"] = true;
entry.CurrentValues["DeletedBy"] = userId;
entry.CurrentValues["Deleted"] = DateTime.Now;
break;
case EntityState.Modified:
entry.CurrentValues["UpdatedBy"] = userId;
entry.CurrentValues["Updated"] = DateTime.Now;
break;
case EntityState.Added:
entry.CurrentValues["IsDeleted"] = false;
entry.CurrentValues["CreatedBy"] = userId;
entry.CurrentValues["Created"] = DateTime.Now;
entry.CurrentValues["Description"] = userId;
break;
default:
break;
}
}
}}}
这是我在 .net core 2.2 中获取用户 ID 的方式
首先您需要在 Startup.cs
中注册
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
然后为您服务
private readonly IHttpContextAccessor _httpContextAccessor;
public UserService(
IHttpContextAccessor httpContextAccessor)
{
}
var currentUserGuid = _httpContextAccessor?.HttpContext?.User?.FindFirst(UserClaimsKey.Sub)?.Value;
尝试将 IHttpContextAccessor
直接注入 ApplicationDbContext
:
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor= httpContextAccessor;
}
//other methods
private void CheckBeforeSaving()
{
var userId = _httpContextAccessor?.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
//...
}
}
private async Task<ApplicationUser> GetUserDetailsAnsyc()
{
return await userManager.GetUserAnsync(HttpContext.User);
}
var user = await GetUserDetailsAnsyc();
Console.WriteLine(user.Id.ToString());
我对 ASP.NET Core 还很陌生。 我想创建 ASP.NET Core 2.2 WebAPI,具有 Entity Framework Core 和 ASP.NET Identity。 另外,我想使用 JWT 通过令牌来保护对 WebAPI 的访问。
我已成功将用户插入数据库并从我的 API 取回令牌,并且令牌身份验证正在运行。
但是,我还想软删除数据库记录并跟踪谁拥有 deleted/updated/added 记录。
测试 table 是国家,其中字段只有 Title
和 Description
.
到目前为止,我已经颠倒了互联网,但没有帮助:(
我试过的最后一件事是(userId 是 null
):
在startup.cs:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在我的 AppDbContext.cs
public class AppDbContext : IdentityDbContext<AppUser>{ public AppDbContext(DbContextOptions options) : base(options) { } public DbSet<AppUser> AppUsers { get; set; } public DbSet<Country> Countries { get; set; } // just for testing protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // TODO - IGNORE THIS //builder.Entity<AppUser>().Property<bool>("IsDeleted"); //builder.Entity<AppUser>().HasQueryFilter(m => EF.Property<bool>(m, "IsDeleted") == false); } public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)) { CheckBeforeSaving(); return (await base.SaveChangesAsync(true, cancellationToken).ConfigureAwait(false)); } private void CheckBeforeSaving() { var httpContextAccessor = this.GetService<IHttpContextAccessor>(); var userId = httpContextAccessor?.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); foreach (var entry in ChangeTracker.Entries()) { switch (entry.State) { case EntityState.Detached: break; case EntityState.Unchanged: break; case EntityState.Deleted: entry.State = EntityState.Modified; entry.CurrentValues["IsDeleted"] = true; entry.CurrentValues["DeletedBy"] = userId; entry.CurrentValues["Deleted"] = DateTime.Now; break; case EntityState.Modified: entry.CurrentValues["UpdatedBy"] = userId; entry.CurrentValues["Updated"] = DateTime.Now; break; case EntityState.Added: entry.CurrentValues["IsDeleted"] = false; entry.CurrentValues["CreatedBy"] = userId; entry.CurrentValues["Created"] = DateTime.Now; entry.CurrentValues["Description"] = userId; break; default: break; } } }}}
这是我在 .net core 2.2 中获取用户 ID 的方式
首先您需要在 Startup.cs
中注册services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
然后为您服务
private readonly IHttpContextAccessor _httpContextAccessor;
public UserService(
IHttpContextAccessor httpContextAccessor)
{
}
var currentUserGuid = _httpContextAccessor?.HttpContext?.User?.FindFirst(UserClaimsKey.Sub)?.Value;
尝试将 IHttpContextAccessor
直接注入 ApplicationDbContext
:
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor= httpContextAccessor;
}
//other methods
private void CheckBeforeSaving()
{
var userId = _httpContextAccessor?.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
//...
}
}
private async Task<ApplicationUser> GetUserDetailsAnsyc()
{
return await userManager.GetUserAnsync(HttpContext.User);
}
var user = await GetUserDetailsAnsyc();
Console.WriteLine(user.Id.ToString());