使用Umbraco 7的异步控制器操作返回字符串
是否可以在Umbraco SurfaceController(和UmbracoApiController)中使用异步操作
我尝试了以下代码
public async Task HandleLogin(LoginViewModel model) { await Task.Delay(1000); return PartialView("Login", model); }
虽然它在调用动作时正确编译,但是一旦命中await,动作似乎就会返回,并返回一个字符串
System.Threading.Tasks.Task`1 [System.Web.Mvc.ActionResult]
控制器当然inheritance自SurfaceController ,我想知道这是不是问题?
如果这不可能,是否有任何变通方法来实现异步操作行为?
任何帮助都会感激不尽!
Umbraco中的SurfaceControllers最终派生自System.Web.Mvc.Controller但是它们具有自定义动作调用程序( RenderActionInvoker )集。
RenderActionInvokerinheritance自ContollerActionInvoker 。 为了处理异步操作,它应该从AsyncContolkerActionInvoker派生。 RenderActionInvoker仅覆盖findaction方法,因此更改为从AsyncContolkerActionInvoker派生很容易。
一旦我使用此更改重新编译Umbraco.Web,异步操作就可以正常工作。
我猜你可以在每个class级上指定一个新的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 Test() { await Task.Delay(10000); return PartialView("TestPartial"); } }
虽然没有测试过这种做事方式。
仅供参考我为跟踪器添加了一个问题: http : //issues.umbraco.org/issue/U4-5208
虽然有一个工作:
创建自定义异步呈现操作调用(如上所述):
public class FixedAsyncRenderActionInvoker : 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; } }
创建自定义渲染mvc控制器:
public class FixedAsyncRenderMvcController : RenderMvcController { public FixedAsyncRenderMvcController() { this.ActionInvoker = new FixedAsyncRenderActionInvoker(); } }
创建自定义渲染控制器工厂:
public class FixedAsyncRenderControllerFactory : RenderControllerFactory { public override IController CreateController(RequestContext requestContext, string controllerName) { var controller1 = base.CreateController(requestContext, controllerName); var controller2 = controller1 as Controller; if (controller2 != null) controller2.ActionInvoker = new FixedAsyncRenderActionInvoker(); return controller1; } }
创建一个umbraco启动处理程序并用上面的自定义部分替换必要的部分:
public class UmbracoStartupHandler : ApplicationEventHandler { protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { DefaultRenderMvcControllerResolver.Current.SetDefaultControllerType(typeof(FixedAsyncRenderMvcController)); FilteredControllerFactoriesResolver.Current.RemoveType(); FilteredControllerFactoriesResolver.Current.AddType(); base.ApplicationStarting(umbracoApplication, applicationContext); } }
- 当没有数据发布时,在页面加载时显示MVC Razorvalidation错误
- 如何使用“required”htmlattribute向mvc 5 razor视图文本输入编辑器添加自定义错误消息
- 将video上传/保存到数据库或文件系统
- ASP.NET MVC C#:将来自多个表/查询的数据引入视图
- 如何在asp.net的文本框中提交HTML标签?
- 如何在Asp.Net Core中设置日期绑定的文化?
- MVC 3尝试将URL启动到View而不是控制器操作
- ResouceManager有时会错误地加载ASP.Net MVC资源文件
- 有没有更有效的方法来处理C#ASP.NET上的亚马逊产品广告API(特别是MVC 5)?