使用核心标识 MVC 登录用户的日志 IP ASP.net



我想要实现的目标:

将命中特定操作/控制器的用户的 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);
}
}

此解决方案的问题:

  1. 当请求命中标有此属性的操作时,请求将需要大约 1-2 秒,直到它实际处理该操作。
  2. 用户管理器
  3. 由依赖注入检索,但我也会在我的一些操作中访问用户管理器实例,这会导致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反而修复了我遇到的第二个问题。但是,如果这是正确的选择,我仍然如何在后台线程或类似线程中执行此操作。

所以我通过使用在后台线程上将其项目取消排队的ConcurrentQueue解决了我的第一个问题。我在这篇博文中找到了这个解决方案。它只需要一些轻微的修改就可以解决这个问题。

最新更新