【问题标题】:How can i call an Async method from a filter attribute in ASP.NET MVC5 [duplicate]如何从 ASP.NET MVC5 中的过滤器属性调用异步方法 [重复]
【发布时间】:2020-05-17 06:05:59
【问题描述】:

我正在尝试从我的自定义FilterAttribute 发出async/await 请求,如下所示。我遇到的问题是,这是MVC5,并且我知道过滤器属性没有异步基类,所以我必须使用Task 来实现相同的结果。我知道使用Task 可能会影响性能,但我可以想到任何其他方法来解决这个问题。

我希望拨打async/await 的方法是_authService.IsUserSessionValid

我需要调用一个异步方法来访问数据库并返回一个值。我无法做到这一点,这就是为什么我将呼叫包装在Task 中我意识到OnActionExecuting 被调用了两次,filterContext.Result 也不会像我想的那样将用户重定向到操作"SignOut"它会。我该如何解决这个问题?

public class SingleSessionValidationFilterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var _authService = (IAuthService)DependencyResolver.Current.GetService(typeof(IAuthService));
            var _formsAuthenticationHelper = (IFormsAuthenticationHelper)DependencyResolver.Current.GetService(typeof(IFormsAuthenticationHelper));

            var currentUserId = _formsAuthenticationHelper.GetLoggedInUserId();
            var currentCookieId = HttpContext.Current.Request.Cookies["CookieKey"]?.Value;
            var task = Task.Run(
                async () => _authService.IsUserSessionValid(new UserSessionValidityCheckerViewModel()
                {
                    CookieId = currentCookieId,
                    UserId = currentUserId
                }));

            task.Wait();

            if (task.Result.IsCompleted)
            {
                var value = task.Result.Result;
                if (!value)
                {
                    filterContext.Result = new System.Web.Mvc.RedirectToRouteResult(
                        new RouteValueDictionary
                        {
                            {"action", "SignOut"},
                            {"controller", "Account"}
                        });
                }
            }

        }

【问题讨论】:

  • 在你的异步 lambda 中没有等待。
  • 这个IsUserSessionValid真的是异步的还是只有你把它包裹在Task.Run中?这背后有什么故事?
  • @WiktorZychla 我正在创建一种跟踪用户会话的方法,该项目很旧并且不使用 IdentityServer 进行身份验证。因此,对于单个会话,当用户登录帐户时(实例 1),当同一用户登录其他地方时(实例2),他们被允许登录,但数据库更新为新的cookie..所以如果用户尝试使用以前的实例,比如点击一个按钮,如果cookie有效,过滤器属性会检查每个操作,如果没有,请退出
  • @WiktorZychla 是的,IsUserSession 是一个异步等待任务
  • Task.Run(); 中不需要 async 这个词。没有可等待的任务,所以无论如何它都会同步运行。

标签: c# asp.net-mvc asp.net-mvc-4 async-await actionfilterattribute


【解决方案1】:

如果 _authService.IsUserSessionValid 返回一个Task<bool> 那么你可以写

await task; // awaits the task, thus making it asynchronous

而不是

task.Wait(); // this will block further execution until the task completes

之后您可以检查结果并重定向。

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    相关资源
    最近更新 更多