2012-10-18 22 views
5

के बाहर Async आपरेशन asp.net MVC के प्रदर्शन करना मैं हर अनुरोध पर एक बादल डेटाबेस से उपयोगकर्ता लोड करने के लिए सक्षम होना चाहते हैं और है कि एक नियंत्रक asp.net MVC के उपयोग करने में अनुरोध पर उपलब्ध है। समस्या यह है कि वर्तमान ढांचा एक्शन फ़िल्टर से एसिंक ऑपरेशन करने का समर्थन नहीं करता है। तो OnActionExecuting, OnAuthorization तरीकों मुझे उदाहरण के लिए इस .. ऐसा करने की अनुमति नहीं है मैं निम्नलिखित कोड है जो काम नहीं करता है (इसलिए यह कोशिश मत करो) .. आप एक अपवाद प्राप्त है: "एक अतुल्यकालिक मॉड्यूल या हैंडलर जबकि एक अतुल्यकालिक पूरा ऑपरेशन अभी भी लंबित था। "कार्रवाई

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; 
    } 
} 

तो क्या ऐसा करने में सक्षम होने का कोई अन्य तरीका है? मुझे लगता है कि बेस कंट्रोलर में एक प्रारंभ निष्पादन विधि है:

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

क्या मैं संभवतः वहां ऐसा कर सकता हूं?

+0

आप [यहां एसिंक एक्शन फ़िल्टर के लिए वोट दे सकते हैं] (https://aspnet.codeplex.com/workitem/9582)। –

+0

मैंने हाल ही में [एक लाइब्रेरी प्रकाशित की है] (https://www.nuget.org/packages/Hydrogen.Extensions.Mvc5.Async) जो एसिंक फ़िल्टर के लिए उचित समर्थन जोड़ता है (भारी रूप से कोड पर आधारित [एएसपी.नेट एमवीसी कोर] (https://github.com/aspnet/Mvc))। स्रोत यहां भी उपलब्ध है: https://github.com/jdaigle/Hydrogen.Extensions.Mvc5। –

उत्तर

10

प्रश्न तीन महीने तो मुझे लगता है कि आप इस के आसपास काम करने में कामयाब हो गया है। वैसे भी, मैं अपना समाधान यहां जोड़ दूंगा, क्योंकि मुझे कुछ ऐसा करना था।

मैं ParallelExtensionsExtras पुस्तकालय से कुछ तरीकों का इस्तेमाल किया। यह मेरी कक्षा है:

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

ध्यान दें कि 'Controller.Request' और कई अन्य गुण हैं' null' अंदर 'DoStuffHereOrInDerivedClassAsync()', बेहतर गुजर जा 'RequestContext' एक तर्क के रूप कुछ सुविधाओं का उपयोग करने के लिए। – deerchao

+0

OnActionExecuting के 'खाली' ओवरराइड क्यों? –

+0

हाय डिर्क, यह दो और डेढ़ साल के बाद से मैं यह लिखा गया है, तो मैं ईमानदारी से याद नहीं कर सकते :) शायद मूल इरादा ओवरराइड सील करने के लिए व्युत्पन्न वर्ग में भ्रम से बचने के लिए किया गया था सकता है - लेकिन वास्तव में करना भूल यह ?! –