2015-08-10 13 views
5

Tôi có ứng dụng MVC5 sử dụng Castle Windsor (http://www.artisancode.co.uk/2014/04/integrating-windsor-castle-mvc/). Gần đây tôi đã cố gắng thêm một phương pháp Async một bộ điều khiển MVC. Khi tôi thực hiện việc này, tôi nhận được thông báo lỗi sau:Hành động Async MVC với Castle Windsor

Phương pháp hành động không đồng bộ 'kiểm tra' trả về Tác vụ, không thể thực thi đồng bộ.

Tôi đã tạo ứng dụng MVC mới trong VS và không nhận được lỗi, vì vậy tôi đoán là tôi đã để lại thứ gì đó trong cấu hình Castle Windsor? Tuy nhiên tôi không biết bắt đầu từ đâu và tôi không thể tìm thấy bất kỳ bài viết nào khi trợ giúp.

câu hỏi Đang cập nhật với mã:

CastleWindsorActionInvoker.cs

public class CastleWindsorActionInvoker : ControllerActionInvoker 
    { 
     private readonly IKernel kernel; 

     public CastleWindsorActionInvoker(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 

     protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) 
     { 
      foreach(IActionFilter filter in filters) 
      { 
       kernel.InjectProperties(null, filter); 
      } 

      return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters); 
     } 

     protected override AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor) 
     { 
      foreach(IAuthorizationFilter filter in filters) 
      { 
       Type type = filter.GetType(); 

       IEnumerable<INamedInstanceAttribute> namedInstanceAttributes = type.GetCustomAttributes(typeof(INamedInstanceAttribute), false) as IEnumerable<INamedInstanceAttribute>; 

       if(namedInstanceAttributes != null) 
       { 
        this.kernel.InjectProperties(namedInstanceAttributes, filter); 
       } 
       else 
       { 
        this.kernel.InjectProperties(null, filter); 
       } 
      } 

      return base.InvokeAuthorizationFilters(controllerContext, filters, actionDescriptor); 
     } 
    } 

WindsorDependencyMvcResolver.cs

public class WindsorDependencyMvcResolver : System.Web.Mvc.IDependencyResolver 
    { 
     public IWindsorContainer container { get; protected set; } 

     public WindsorDependencyMvcResolver(IWindsorContainer container) 
     { 
      if(container == null) 
      { 
       throw new ArgumentNullException("container"); 
      } 

      this.container = container; 
     } 

     public object GetService(Type serviceType) 
     { 
      try 
      { 
       return container.Resolve(serviceType); 
      } 
      catch(ComponentNotFoundException) 
      { 
       return null; 
      } 
     } 

     public IEnumerable<object> GetServices(Type serviceType) 
     { 
      return container.ResolveAll(serviceType).Cast<object>(); 
     } 
    } 

cs CastleWindsorMvcFactory

public class CastleWindsorMvcFactory : DefaultControllerFactory 
    { 
     private readonly IKernel kernel; 

     public CastleWindsorMvcFactory(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 

     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
     { 
      if(controllerType == null) 
      { 
       throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path)); 
      } 

      Controller controller = (Controller)kernel.Resolve(controllerType); 

      if(controller != null) 
      { 
       controller.ActionInvoker = kernel.Resolve<IActionInvoker>(); 
      } 

      return controller; 
     } 

     public override void ReleaseController(IController controller) 
     { 
      kernel.ReleaseComponent(controller); 
     } 
    } 

Global.asax

ControllerBuilder.Current.SetControllerFactory(new CastleWindsorMvcFactory(container.Kernel)); 

DependencyResolver.SetResolver(new WindsorDependencyMvcResolver(container)); 

MVC Action

public async Task<ActionResult> Index() 
     { 
      return View(); 
     } 
+0

Bắt đầu bằng cách hiển thị cho chúng tôi mã của bạn –

+0

Hành động này có được gọi bằng phương pháp Html.Action ở chế độ xem khác không? –

+0

Đây chỉ là phương pháp thử nghiệm, được gọi trực tiếp bằng cách nhập url vào trình duyệt – markpirvine

Trả lời

2

tôi đã làm việc trên một cái gì đó khác và tình cờ gặp article này. Dựa trên nó, tôi đã thay đổi CastleWindsorActionInvoker của mình để kế thừa từ AsyncControllerActionInvoker và tôi đã có thể chạy hành động async của mình.

Cảm ơn mọi đề xuất!

1

Disclaimer: các liên kết dưới đây là dành cho một sample Github project tôi tạo ra.

Tôi nghi ngờ rằng bài viết đề xuất lối sống sai cho bộ điều khiển của bạn. Tôi thường sử dụng thoáng, like so:

public class ControllersInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Classes.FromThisAssembly() 
      .BasedOn<IController>() 
      .LifestyleTransient()); 

     container.Register(Classes.FromThisAssembly() 
      .BasedOn<IHttpController>() 
      .LifestyleTransient()); 
    } 
} 

Sử dụng trình cài đặt, this action giải quyết tốt:

public async Task<ActionResult> Login(Models.LoginFormModel model, string returnUrl = "") 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      /* ... more code ... */ 
     } 
    } 
    catch (Exception ex) 
    { 
     HandleException(ex); 
    } 

    // If we got this far, something failed; redisplay form 
    return View(model); 
} 
Các vấn đề liên quan