2012-10-18 10 views
5

Ich möchte in der Lage sein, einen Benutzer aus einer Cloud-Datenbank bei jeder Anfrage zu laden und diese auf der Anfrage in einem Controller mit asp.net mvc verfügbar. Das Problem besteht darin, dass das aktuelle Framework keine asynchronen Vorgänge von Aktionsfiltern unterstützt. So OnActionExecuting, OnAuthorization Methoden erlauben mir dies nicht .. zum Beispiel habe ich den folgenden Code, der nicht funktioniert (also nicht versuchen) .. Sie erhalten eine Ausnahme: "Ein asynchrones Modul oder Handler während einer asynchronen abgeschlossen Operation war noch ausstehend. "Führen Sie Async-Vorgang asp.net MVC außerhalb der Aktion

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

So gibt es eine andere Weise in der Lage zu sein, dies zu tun? Ich bemerke, es gibt eine begin execute-Methode in der Basis-Controller:

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

Könnte ich es dort möglicherweise tun?

+0

können Sie [Abstimmung für async Aktionsfilter hier] (https://aspnet.codeplex.com/workitem/9582). –

+0

Ich habe vor kurzem [eine Bibliothek veröffentlicht] (https://www.nuget.org/packages/Hydrogen.Extensions.Mvc5.Async), die die richtige Unterstützung für asynchrone Filter (stark auf Code aus [ASP.NET MVC Kern] (https://github.com/aspnet/Mvc)). Quelle ist auch hier verfügbar: https://github.com/jdaigle/Hydrogen.Extensions.Mvc5. –

Antwort

10

Die Frage ist drei Monate alt, also denke ich, dass Sie es geschafft haben, dies zu umgehen. Wie auch immer, ich werde hier meine Lösung hinzufügen, da ich etwas Ähnliches machen musste.

Ich habe ein paar Methoden aus der ParallelExtensionsExtras Bibliothek verwendet. Das ist meine Klasse:

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

Beachten Sie, dass 'Controller.Request' und viele andere Eigenschaften in' DoStuffHereOrInDerivedClassAsync() '' 'null' 'sind, übergeben Sie besser' RequestContext' als Argument für den Zugriff auf bestimmte Funktionen. – deerchao

+0

Warum die 'leere' Überschreibung von OnActionExecuting? –

+0

Hallo Dirk, es ist zweieinhalb Jahre her, seit ich das geschrieben habe, also kann ich mich ehrlich gesagt nicht erinnern :) Vielleicht war die ursprüngliche Absicht, die Überschreibung zu versiegeln, um Verwirrung in den abgeleiteten Klassen zu vermeiden - aber vergessen zu tun es?! –

Verwandte Themen