2012-10-19 14 views
9

Ich habe meine Authentifizierungslogik in einer Klasse, abgeleitet von System.Web.Http.AuthorizeAttribute (überschriebene OnAuthorization-Methode). Ich rufe von dieser Methode eine DB an und ich möchte, dass dieser Aufruf asynchron ist (glücklicherweise ermöglicht dies die neue asynchrone ADO.NET-API).Async-Aktionsfilter: Async & AuthorizeAttribute in der ASP.NET-Web-API

Dann wende ich dieses Attribut an einen Controller an, um alle Anrufe durch den Authentifizierungsfilter gehen zu lassen. So weit, ist es gut.

Aber dabei stoße ich auf das folgende Problem. Das Framework (ASP.NET Web API) scheint nicht bewusst zu sein, was meine Absichten sind :) Es sieht so aus, als würde es mit der Action-Ausführung des Controllers fortfahren, bevor die OnAuthorizaion-Methoden meines Filters beendet werden (kehrt vom asynchronen Aufruf zurück) Ausnahme vom Framework a la "Die Anforderungsverarbeitung wurde beendet, bevor alle ausstehenden asynchronen Operationen abgeschlossen sind."

Gibt es einen Out-of-the-Box-Weg, um damit umzugehen?

Danke!

P.S. Mein Bauchgefühl sagt, dass ich für eine benutzerdefinierte Aktion Filter Erstellung bin. Dann muss ich ExecuteActionFilterAsync überschreiben und meine Authentifizierung dort alle task-related stuff selbst ohne Hilfe von der Framework-Seite zu tun ..)

+0

Alle Filterschnittstellen, die Ihnen das Framework zur Verfügung stellt, sind asynchron-aware. Ich nehme an, Sie arbeiten mit Standardimplementierungen derjenigen, die synchrone APIs exponieren. Arbeiten Sie mit 'IAuthorizationFilter', wie in der folgenden Antwort vorgeschlagen. – tugberk

Antwort

5

Ok, hier ist das, was ich mit kam (nach einem Blick unter der Haube mit Reflektor nehmen):

public class SecurityFilterAttribute : FilterAttribute, IAuthorizationFilter 
{ 
    public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) 
    { 
     await OnAuthentication(actionContext); 

     return actionContext.Response ?? await continuation(); 
    } 

    private async Task OnAuthentication(HttpActionContext actionContext) 
    { 
     //some lengthy I/O operations (XXXAsync/await) 
    } 
} 

diese Weise an einen Controller/Aktion angewandt wird, die gesamte Logik wird in der richtigen Reihenfolge ausgeführt werden während der Thread während der I/O nicht blockiert. Nicht sehr respektvoll gegenüber Stornierung. Aber sollte für meine Zwecke in Ordnung sein ..

Wie auch immer, ich frage mich wirklich, was Web-API-Ersteller nicht ähnlich gehen ... Ideen?

Verwandte Themen