我有一个用 C# 编写并使用 ASP.NET Core Identity 的 ASP.NET Core MVC 项目。
我有一个具有多个操作的控制器,用于从数据库读取/写入,其中查询依赖于每个请求的
ApplicationUser.Id
值。
如何避免不断调用以下方法来查找当前的
ApplicationUser
并获取它们的Id
?
protected async Task<ApplicationUser> GetCurrentApplicationUser()
{
var httpContextUser = HttpContext.User;
return await _userManager.GetUserAsync(httpContextUser);
}
我纯粹从性能角度看待这个问题。
我们将不胜感激,谢谢。
您应该使用缓存,它可以是内存缓存或分布式缓存(如 redis 或任何其他)。
只需将
ApplicationUser
存储在缓存中即可轻松检索。
另一个选项是在claimn中设置用户id,并在
User.Claims
对象中搜索它。
这是一种方法。这是有效的,因为
_applicationUserTask
只执行一次,但可以等待多次。这意味着它不会一遍又一遍地执行。
我没有包含它,但你可以定义一个像
IApplicationUserAccessor
这样的接口。或者您可以直接向 DI 容器注册此类。这取决于您是否想将接口或具体类注入到控制器中。
重要的是这必须注册为作用域。
services.AddScoped<ApplicationUserAccessor>();
...确保每个请求都有一个新实例。
public class ApplicationUserAccessor
{
private readonly Task<ApplicationUser> _applicationUserTask;
public ApplicationUserAccessor(
IHttpContextAccessor httpContextAccessor,
IUserManager userManager)
{
_applicationUserTask = GetUserAsync(httpContextAccessor, userManager);
}
public async Task<ApplicationUser> GetCurrentApplicationUser()
{
return await _applicationUserTask.ConfigureAwait(false);
}
private static async Task<ApplicationUser> GetUserAsync(
IHttpContextAccessor httpContextAccessor,
IUserManager userManager)
{
HttpContext httpContext = httpContextAccessor.HttpContext;
ClaimsPrincipal httpContextUser = httpContext?.User;
if (httpContextUser == null)
{
return null;
}
return await userManager.GetApplicationUser(httpContextUser);
}
}
您还可以将其与缓存结合起来。您可以将寿命较长的缓存实例注入此类中。