You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core SaveChanges方法中System.Threading.Thread.CurrentPrincipal为空的问题求助

Fix: Can't Get Authenticated User in EF Core SaveChanges in Blazor

I've run into this exact issue before with Blazor and EF Core—thread-bound principal objects just don't play nice with async contexts like Blazor's component lifecycle. Let's break down why your current approach isn't working and how to fix it properly.

Why Your Current JWT Setup Fails

Thread.CurrentPrincipal is tied to the specific thread that runs the OnTokenValidated event. But in Blazor (especially Blazor Server), async operations frequently switch threads, and that thread-bound principal doesn't carry over. ClaimsPrincipal.Current has the same problem—it relies on outdated thread context logic that doesn't work in modern async ASP.NET Core apps.

Solution 1: Use IHttpContextAccessor (Blazor Server)

For Blazor Server, the most straightforward fix is to use IHttpContextAccessor, which uses AsyncLocal under the hood to track the current user's context across async threads.

Step 1: Register the Accessor

Add this to your Program.cs to make the accessor available for injection:

builder.Services.AddHttpContextAccessor();

Step 2: Inject It Into Your DbContext

Update your BlazorRestaurantDbContext constructor to accept the accessor:

private readonly IHttpContextAccessor _httpContextAccessor;

public BlazorRestaurantDbContext(DbContextOptions<BlazorRestaurantDbContext> options, IHttpContextAccessor httpContextAccessor)
    : base(options)
{
    _httpContextAccessor = httpContextAccessor;
}

Step 3: Fetch the User in ValidateAndSetDefaults

Replace your existing user lookup code with this:

private void ValidateAndSetDefaults()
{
    // ... keep your existing code for IPs and assembly name ...

    string rowCreationUser = "Unknown";
    if (entities.Any(p => p is IOriginatorInfo))
    {
        ipAddresses = String.Join(",", GetCurrentHostIPv4Addresses());
        assemblyFullName = System.Reflection.Assembly.GetEntryAssembly().FullName;
        
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext?.User?.Identity != null && httpContext.User.Identity.IsAuthenticated)
        {
            rowCreationUser = httpContext.User.Identity.Name;
        }
    }

    // ... rest of your validation logic ...
}

Solution 2: Custom IUserContext Service (Cross-Platform Friendly)

If you might ever switch to Blazor WebAssembly or want a more decoupled approach, create a dedicated user context service:

Step 1: Define the Interface

public interface IUserContext
{
    string GetCurrentUserName();
}

Step 2: Implement for Blazor Server

public class ServerUserContext : IUserContext
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ServerUserContext(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public string GetCurrentUserName()
    {
        var user = _httpContextAccessor.HttpContext?.User;
        return user?.Identity?.IsAuthenticated == true ? user.Identity.Name : "Unknown";
    }
}

Step 3: Register the Service

In Program.cs:

builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<IUserContext, ServerUserContext>();

Step 4: Inject and Use in DbContext

private readonly IUserContext _userContext;

public BlazorRestaurantDbContext(DbContextOptions<BlazorRestaurantDbContext> options, IUserContext userContext)
    : base(options)
{
    _userContext = userContext;
}

// Then in ValidateAndSetDefaults:
rowCreationUser = _userContext.GetCurrentUserName();

Key Notes

  • For Blazor WebAssembly: IHttpContextAccessor doesn't work client-side, so you'll need to pass user info from the client to your API endpoints, or fetch it directly from the JWT token in your backend API logic.
  • Double-check your middleware order in Program.cs: Make sure UseAuthentication() and UseAuthorization() come after UseBlazorFrameworkFiles() and UseRouting(), but before UseEndpoints().

内容的提问来源于stack exchange,提问作者Eduardo Fonseca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:17:40