2012-10-18 35 views
5

Tôi muốn có thể tải người dùng từ cơ sở dữ liệu đám mây theo từng yêu cầu và có sẵn trên yêu cầu trong bộ điều khiển bằng cách sử dụng asp.net mvc. Vấn đề là khung công tác hiện tại không hỗ trợ thực hiện các hoạt động không đồng bộ từ các bộ lọc hành động. Vì vậy, OnActionExecuting, OnAuthorization phương pháp không cho phép tôi làm điều này .. ví dụ tôi có đoạn mã sau mà không làm việc (do đó, không thử nó) .. Bạn nhận được một ngoại lệ: "Một mô-đun không đồng bộ hoặc xử lý hoàn thành trong khi một không đồng bộ hoạt động vẫn đang chờ xử lý. "Thực hiện hoạt động Async asp.net mvc bên ngoài hành động

protected async override void OnAuthorization(AuthorizationContext filterContext) 
{ 
    var user = filterContext.HttpContext.User; 
    if (!user.Identity.IsAuthenticated) 
    { 
    HandleUnauthorizedRequest(filterContext); 
    return; 
    } 

    using (var session = MvcApplication.DocumentStore.OpenAsyncSession()) 
    { 
    User currentUser = await session.LoadAsync<User>(user.Identity.Name); 
    if (currentUser == null) 
    { 
     HandleUnauthorizedRequest(filterContext); 
     return; 
    } 

    filterContext.HttpContext.Items["User"] = currentUser; 
    } 
} 

Vì vậy, có cách nào khác để có thể thực hiện việc này không? Tôi nhận thấy có một phương pháp bắt đầu thực hiện trong Bộ điều khiển cơ sở:

protected override IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) 
{ 
    return base.BeginExecute(requestContext, callback, state); 
} 

Tôi có thể làm điều đó ở đó không?

+0

Bạn có thể [bỏ phiếu cho bộ lọc hành động không đồng bộ ở đây] (https://aspnet.codeplex.com/workitem/9582). –

+0

Gần đây tôi đã [xuất bản một thư viện] (https://www.nuget.org/packages/Hydrogen.Extensions.Mvc5.Async) thêm hỗ trợ thích hợp cho các bộ lọc async (dựa trên mã nguồn từ [ASP.NET MVC Core] (https://github.com/aspnet/Mvc)). Nguồn cũng có sẵn tại đây: https://github.com/jdaigle/Hydrogen.Extensions.Mvc5. –

Trả lời

10

Câu hỏi là ba tháng tuổi nên tôi đoán bạn đã xoay xở để giải quyết vấn đề này. Dù sao, tôi sẽ thêm giải pháp của tôi ở đây, như tôi đã phải làm một cái gì đó tương tự.

Tôi đã sử dụng một vài phương pháp từ thư viện ParallelExtensionsExtras. Đây là lớp học của tôi:

public class AsyncControllerBase : Controller 
{ 
    protected override IAsyncResult BeginExecute(System.Web.Routing.RequestContext requestContext, AsyncCallback callback, object state) 
    { 
     return ExecuteCoreAsync(requestContext, state).ToAsync(callback, state); 
    } 

    protected override void EndExecute(IAsyncResult asyncResult) 
    { 
     IAsyncResult baseAsyncResult = ((Task<IAsyncResult>)asyncResult).Result; 
     base.EndExecute(baseAsyncResult); 
    } 

    protected virtual async Task<IAsyncResult> ExecuteCoreAsync(System.Web.Routing.RequestContext requestContext, object state) 
    { 
     await DoStuffHereOrInDerivedClassAsync(); 

     var baseBeginExecuteCompletion = new TaskCompletionSource<IAsyncResult>(); 

     AsyncCallback callback = ar => 
     { 
      baseBeginExecuteCompletion.SetResult(ar); 
     }; 

     // OnActionExecuting will be called at this point 
     var baseAsyncResult = base.BeginExecute(requestContext, callback, state); 

     await baseBeginExecuteCompletion.Task; 

     return baseAsyncResult; 
    } 

    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 
    } 
} 
+1

Lưu ý rằng 'Controller.Request' và nhiều thuộc tính khác là' null' bên trong 'DoStuffHereOrInDerivedClassAsync()', tốt hơn là truyền 'RequestContext' làm đối số để truy cập một số tính năng nhất định. – deerchao

+0

Tại sao ghi đè 'rỗng' của OnActionExecuting? –

+0

Xin chào Dirk, đã hai năm rưỡi kể từ khi tôi viết bài này, vì vậy tôi không thể nhớ :) Có thể ý định ban đầu là phong ấn ghi đè để tránh nhầm lẫn trong lớp học có nguồn gốc - nhưng quên thực sự làm nó ?! –

Các vấn đề liên quan