使用Umbraco 7的异步控制器操作返回字符串

Pet*_*eld 9 c# asp.net-mvc umbraco async-await asp.net-mvc-4

是否可以在Umbraco SurfaceController(和UmbracoApiController)中使用异步操作

我尝试了以下代码

public async Task< ActionResult> HandleLogin(LoginViewModel model)
{
    await Task.Delay(1000);
    return PartialView("Login", model);
}
Run Code Online (Sandbox Code Playgroud)

虽然在调用动作时它被正确编译,但是一旦命中await,动作似乎就会返回,并返回一个字符串

System.Threading.Tasks.Task`1 [System.Web.Mvc.ActionResult]

控制器当然继承自SurfaceController,我想知道这是不是问题?

如果这不可能,是否有任何解决方法来实现异步操作行为?

感谢任何帮助!

Pet*_*eld 10

Umbraco中的SurfaceControllers最终派生自System.Web.Mvc.Controller但是它们具有自定义动作调用程序(RenderActionInvoker)集.

RenderActionInvoker继承自ContollerActionInvoker.为了处理异步操作,它应该从AsyncContolkerActionInvoker派生.RenderActionInvoker仅覆盖findaction方法,因此更改为从AsyncContolkerActionInvoker派生很容易.

一旦我使用此更改重新编译Umbraco.Web,异步操作就可以正常工作.

我猜你可以在每个课程上指定一个新的actioninvoker,而不是重新编译整个项目

public class RenderActionInvokerAsync : System.Web.Mvc.Async.AsyncControllerActionInvoker
{

    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
    {
        var ad = base.FindAction(controllerContext, controllerDescriptor, actionName);

        if (ad == null)
        {
            //check if the controller is an instance of IRenderMvcController
            if (controllerContext.Controller is IRenderMvcController)
            {
                return new ReflectedActionDescriptor(
                    controllerContext.Controller.GetType().GetMethods()
                        .First(x => x.Name == "Index" &&
                                    x.GetCustomAttributes(typeof(NonActionAttribute), false).Any() == false),
                    "Index",
                    controllerDescriptor);

            }
        }
        return ad;
    }

}

public class TestController : SurfaceController
{

    public TestController() {
        this.ActionInvoker = new RenderActionInvokerAsync();
    }

    public async Task<ActionResult> Test()
    {
        await Task.Delay(10000);
        return PartialView("TestPartial");

    }
}
Run Code Online (Sandbox Code Playgroud)

虽然没有测试过这种做事方式.