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

基于C#与ASP.NET Core Identity优化GetUserAsync调用性能

优化ASP.NET Core Identity获取当前用户ID的性能方案

从性能角度出发,你可以通过以下几种方式避免重复调用数据库查询当前用户:

1. 直接从Claims提取用户ID

ASP.NET Core Identity默认会将用户ID存入ClaimTypes.NameIdentifier类型的Claim中,完全不需要访问数据库就能直接获取:

private string GetCurrentUserId()
{
    return HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
}

这是性能最优的方案,因为Claim信息已经包含在请求的身份凭证里,没有任何数据库开销。

2. 请求周期内缓存用户信息

如果除了ID还需要用户的其他少量字段,可以在单个请求开始时查询一次用户数据,然后缓存到HttpContext.Items中,整个请求生命周期内复用:

第一步:实现请求过滤器

public class CurrentUserCacheFilter : IAsyncActionFilter
{
    private readonly UserManager<ApplicationUser> _userManager;

    public CurrentUserCacheFilter(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var httpContext = context.HttpContext;
        if (httpContext.User.Identity.IsAuthenticated)
        {
            var user = await _userManager.GetUserAsync(httpContext.User);
            // 按需缓存ID或完整用户对象
            httpContext.Items["CurrentUserId"] = user.Id;
            // httpContext.Items["CurrentUser"] = user;
        }
        await next();
    }
}

第二步:注册过滤器

在Program.cs中添加过滤器配置:

builder.Services.AddControllersWithViews(options =>
{
    options.Filters.Add<CurrentUserCacheFilter>();
});

第三步:控制器内复用缓存

string currentUserId = HttpContext.Items["CurrentUserId"] as string;

这样整个请求过程中只会执行一次数据库查询,后续操作直接读取缓存。

3. 自定义Claims扩展常用字段

如果需要的用户字段不止ID(比如昵称、角色),可以在登录时将这些字段添加到Claims中,之后直接从Claims读取,彻底避免数据库查询:

第一步:自定义Claims生成器

public class CustomUserClaimsFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
    public CustomUserClaimsFactory(UserManager<ApplicationUser> userManager, 
        IOptions<IdentityOptions> optionsAccessor) 
        : base(userManager, optionsAccessor)
    {
    }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
    {
        var identity = await base.GenerateClaimsAsync(user);
        // 添加需要的自定义字段
        identity.AddClaim(new Claim("NickName", user.NickName));
        identity.AddClaim(new Claim("Role", user.Role));
        return identity;
    }
}

第二步:注册自定义Factory

builder.Services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, CustomUserClaimsFactory>();

第三步:直接读取Claims

string nickName = HttpContext.User.FindFirstValue("NickName");

注意:这种方式适合不常变动的用户字段,如果用户信息更新,需要重新登录才能同步Claims数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:58:17