将击中特定操作/控制器的用户的IP保存到我的数据库中。另外,由于此过程会花费大量时间,因此如果在后台线程或类似线程上执行该过程将非常好。
创建看起来像这样的CustomAuthorizeAttribute:
public class LoggedAuthorizeAttribute : TypeFilterAttribute
{
public LoggedAuthorizeAttribute() : base(typeof(LoggedAuthorizeFilter))
{
}
}
public class LoggedAuthorizeFilter : IAuthorizationFilter
{
private readonly UserManager<User> _userManager;
public LoggedAuthorizeFilter(UserManager<User> userManager)
{
_userManager = userManager;
}
public async void OnAuthorization(AuthorizationFilterContext context)
{
if (!context.HttpContext.User.Identity.IsAuthenticated)
return;
var user = await _userManager.GetUserAsync(context.HttpContext.User);
var remoteIpAddress = context.HttpContext.Connection.RemoteIpAddress;
user.UserLogins.Add(new UserLogin
{LoggedInOn = DateTimeOffset.UtcNow, LoggedInFrom = remoteIpAddress});
await _userManager.UpdateAsync(user);
}
}
该解决方案存在的问题:
InvalidOperationException
告诉A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext, however instance members are not guaranteed to be thread safe. This could also be caused by a nested query being evaluated on the client, if this is the case rewrite the query avoiding nested invocations.
。感谢您提供任何帮助。
根据Kirk Larkin
的建议,实现IAsyncActionFilter可以解决我遇到的第二个问题。但是,即使这是正确的选择,我仍将如何在后台线程或类似线程中执行此操作。
答案 0 :(得分:0)
因此,我使用ConcurrentQueue
修复了我的第一个问题,该问题将其项在后台线程上出队。我在this博客文章中找到了此解决方案。只需稍作修改即可解决此问题。