使用ASP.net核心身份MVC

时间:2019-06-03 16:20:56

标签: c# asp.net-core asp.net-core-identity

我要实现的目标:

将击中特定操作/控制器的用户的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. 通过依赖关系注入检索UserManager,但我还在某些操作中访问UserManager实例,这导致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可以解决我遇到的第二个问题。但是,即使这是正确的选择,我仍将如何在后台线程或类似线程中执行此操作。

1 个答案:

答案 0 :(得分:0)

因此,我使用ConcurrentQueue修复了我的第一个问题,该问题将其项在后台线程上出队。我在this博客文章中找到了此解决方案。只需稍作修改即可解决此问题。