我需要你的帮助!我已经有一段时间了,我无法弄明白。假设我们有以下控制器:
class NotifierController : MyBaseController {
...
[HttpGet]
[CanNotifyUser]
public async Task<ActionResult> NotifyUser(string id)
{
return View(await DataBase.Users.FindAsync(id));
}
// More actions decorated with the CanNotifyUserAttribute attribute
}
DataBase
是MyBaseController
中定义的属性,如:
static ApplicationDbContext _appDbContext;
public ApplicationDbContext DataBase
{
get { return _appDbContext ?? (_appDbContext = new ApplicationDbContext()); }
}
ApplicationDbContext
继承自IdentityDbContext<MyUser>
,其中MyUser
继承自IdentityUser
。所以,我的问题(我认为)来自自定义操作过滤器CanNotifyUserAttribute
,其OnActionExecuting
覆盖定义为(删除所有检查以尽可能减少):
public override async void OnActionExecuting(ActionExecutingContext filterContext)
{
NotifierController controller = filterContext.Controller as NotifierController;
Boss boss = await controller.DataBase.Bosses.FindAsync(filterContext.HttpContext.User.Identity.GetUserId());
object id = filterContext.ActionParameters["id"];
User user = await controller.DataBase.Users.FindAsync(id.ToString());
if (user.Department.Id != boss.Department.Id)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new
{
action = "Login",
controller = "Account",
returnUrl = controller.Url.Action("NotifyUser", new { id = id })
}));
}
base.OnActionExecuting(filterContext);
}
使用此属性的想法是验证老板是否仅向其部门的用户发送通知。现在出现了奇怪的部分,这只是在我第一次尝试向用户发送通知时发生(无论是否属于同一部门),错误源于:
[InvalidOperationException:在异步操作仍处于挂起状态时完成异步模块或处理程序。]
如果我尝试(在错误之后)相同的请求(即通知用户),它将按照重定向或发送通知的方式工作。
根据this post我可能会在异步任务完成之前完成请求(如果我理解的话),但我一直在使用的所有任务都是await
,所以我不知道知道这个错误可能来自哪里。希望您能够帮助我。提前谢谢!
答案 0 :(得分:0)
您正试图通过将OnActionExecuting
变成async void
来对过滤器实施异步行为。 asnyc void
方法仅应在异步事件处理程序的上下文中使用,因为它们具有特殊的错误处理语义,并且调用过程“无法”等待在(filter-)方法主体内部执行的任务(对于进一步阅读,请考虑this Stephen Cleary的出色文章。
因此,对于ASP.NET Core,请考虑使用IAsyncActionFilter接口。
过滤器通过不同的接口定义支持同步和异步实现。异步过滤器定义单个OnStageExecutionAsync方法。此方法接受一个FilterTypeExecutionDelegate委托,该委托执行过滤器的管道阶段。 (Filters in ASP.NET Core)
所以不是...
public override async void OnActionExecuting(ActionExecutingContext filterContext)
...使用:
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
有关如何使用此功能的更多说明,请参见:Async OnActionExecuting in ASP.NET Core's ActionFilterAttribute