【发布时间】: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