使用异步控制器的强类型RedirectToAction(Futures)

Bar*_*xto 7 c# asynchronous asp.net-mvc-futures asp.net-mvc-5

有这个代码,它给了我一个警告: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

    public async Task<ActionResult> Details(Guid id)
    {
        var calendarEvent = await service.FindByIdAsync(id);
        if (calendarEvent == null) return RedirectToAction<CalendarController>(c => c.Index());
        var model = new CalendarEventPresentation(calendarEvent);
        ViewData.Model = model;
        return View();
    }

    public async Task<RedirectResult> Create(CalendarEventBindingModel binding)
    {
        var model = service.Create(binding);
        await context.SaveChangesAsync();
        return this.RedirectToAction<CalendarController>(c => c.Details(model.CalendarEventID));
    }
Run Code Online (Sandbox Code Playgroud)

如果我添加await运算符我得到:

Error CS4034 The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.

如果我添加这样的async修饰符:

return this.RedirectToAction<CalendarController>(async c => await c.Details(model.CalendarEventID));
Run Code Online (Sandbox Code Playgroud)

错误是 Error CS1989 Async lambda expressions cannot be converted to expression trees

那么我如何使用强类型的RedirectToAction(我使用MVC Futures)和异步控制器?

小智 3

我已经弄清楚了!

我有一个基本控制器,并且有一个用于异步重定向的扩展方法

protected ActionResult RedirectToAsyncAction<TController>(Expression<Func<TController, Task<ActionResult>>> action)
        where TController : Controller
    {
        Expression<Action<TController>> convertedFuncToAction = Expression.Lambda<Action<TController>>(action.Body, action.Parameters.First());
        return ControllerExtensions.RedirectToAction(this, convertedFuncToAction);
    }
Run Code Online (Sandbox Code Playgroud)

这将防止出现警告。然后你可以从你的控制器调用 RedirectToAsyncAction 。

public ActionResult MyAction()
    {
       // Your code
        return RedirectToAsyncAction<MyController>(c => c.MyAsyncAction(params,..)); // no warnings here
    }
Run Code Online (Sandbox Code Playgroud)