2012-10-19 11 views
9

Ho la mia logica di autenticazione in una classe, derivata da System.Web.Http.AuthorizeAttribute (metodo OnAuthorization sovrascritto). Faccio una chiamata a un DB da quel metodo e voglio che quella chiamata sia asincrona (fortunatamente, la nuova API async di ADO.NET lo consente).filtro azione asincrono: Async e AuthorizeAttribute in ASP.NET WEB API

Quindi applico questo attributo a un controller per fare in modo che tutte le chiamate passino attraverso il filtro di autenticazione. Fin qui tutto bene.

Ma così facendo mi imbatto nel seguente problema. Il framework (API Web ASP.NET) non sembra essere a conoscenza di quali sono le mie intenzioni :) Sembra che proceda con l'esecuzione dell'azione del controller prima che i metodi OnAuthorizaion del mio filtro finiscano (restituisce dalla chiamata asincrona). Di qui la eccezione dal framework a la "elaborazione delle richieste terminata prima che tutte le operazioni asincrone siano completate .."

Esiste un modo immediato per affrontarlo?

Grazie!

P.S. Il mio istinto mi dice che sono in cerca di una creazione personalizzata del filtro azione. Quindi dovrò sovrascrivere ExecuteActionFilterAsync e fare l'autenticazione lì gestendo tutto il materiale relativo alle attività senza alcun aiuto dal lato quadro ..)

+0

Tutte le interfacce di filtro, fornite dal Framework, sono asincrone. Presumo che tu stia lavorando con le implementazioni predefinite di quelle che espongono le API sincrone. lavorare con 'IAuthorizationFilter' come suggerito nella risposta qui sotto. – tugberk

risposta

5

Ok, ecco quello che è venuta (dopo aver preso uno sguardo sotto il cofano con riflettore):

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

in questo modo, essendo applicato ad un controllore/azione, tutta la logica viene eseguita in modo corretto mantenendo il filo sbloccato durante I/O. Non molto rispettoso alla cancellazione, però. Ma dovrebbe andar bene per i miei scopi ..

In ogni caso, mi chiedo davvero cosa abbia fatto i creatori di API Web non andare in modo simile ... Idee?

Problemi correlati