IHttpContextAccessorを変数についかし、DbContext生成じに取得する。
ライブラリプロジェクトではIHttpContextAccessorが見つからなかったWeb APIプロジェクトでは追加できたからWebアプリケーション開発テンプレートの場合は問題ないみたい
MyDbContext.cs
private readonly IHttpContextAccessor _httpContextAccessor; public MyDbContext(DbContextOptions<MyDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options) { _httpContextAccessor = httpContextAccessor; }
public class MyDbContext : DbContext { private readonly IHttpContextAccessor _httpContextAccessor; public DbSet<ChangeLog> ChangeLogs { get; set; } public MyDbContext(DbContextOptions<MyDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options) { _httpContextAccessor = httpContextAccessor; } public override int SaveChanges() { var ip = _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString(); var host = System.Net.Dns.GetHostEntry(_httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress)?.HostName; var changeLogs = new List<ChangeLog>(); foreach (var entry in ChangeTracker.Entries().Where(e => e.State == EntityState.Modified || e.State == EntityState.Added || e.State == EntityState.Deleted)) { var entityName = entry.Entity.GetType().Name; foreach (var prop in entry.Properties) { var original = entry.State == EntityState.Added ? null : prop.OriginalValue?.ToString(); var current = prop.CurrentValue?.ToString(); if (original != current) { changeLogs.Add(new ChangeLog { EntityName = entityName, PropertyName = prop.Metadata.Name, OriginalValue = original, CurrentValue = current, IpAddress = ip, HostName = host, ChangedAt = DateTime.UtcNow }); } } } ChangeLogs.AddRange(changeLogs); return base.SaveChanges(); } }
このままだとIHttpContextAccessorが取得できないため、以下を追加
builder.Services.AddHttpContextAccessor();
Programs.cs
var builder = WebApplication.CreateBuilder(args); // ここで登録! builder.Services.AddHttpContextAccessor(); // 他のサービス登録 builder.Services.AddDbContext<AppDbContext>(); var app = builder.Build();