Tanto per sgombrare il campo da equivoci e malintesi, diciamo subito che la compatibilità verso ASP.NET è una configurazione che limita in qualche modo il servizio WCF e che ne restringe le funzionalità. Dunque si tratta di un’opzione che ha senso prendere in considerazione solo per i servizi WCF che ricevono richieste via Web da client ASP.NET AJAX.
La necessità dell’attributo di compatibilità deriva dalla necessità che talvolta si ha di condividere lo stesso ambiente runtime tra pagine ASP.NET e servizi WCF. Un servizio WCF che gira all’interno di IIS è di fatto ospitato da un’applicazione ASP.NET e ne condivide l’AppDomain. Di fatto il servizio WCF e l’applicazione ASP.NET girano side-by-side. Se alcune pagine nella stessa applicazione hanno bisogno di invocare il servizio via AJAX allora configurare il servizio e l’host in modo da supportare il compatibility mode può diventare una vera e propria necessità.
In questo scenario, ogni richiesta inviata al servizio WCF è prima di tutto una richiesta per l’applicazione ASP.NET. Di conseguenza essa viene intercettata da IIS, allungata all’applicazione ASP.NET e quindi passata alla pipeline di ASP.NET per la successiva elaborazione. Ad un certo punto, dopo l’evento PostAuthenticateRequest l’infrastruttura WCF si impadronisce della richiesta e non la restituisce più ad ASP.NET. L’elaborazione della richiesta, dunque, è interamente a carico del runtime di WCF ma, soprattutto, non vi è più interazione con ASP.NET. E’ un problema questo? Dipende. Intanto vediamo cosa comporta di fatto la mancanza interazione con ASP.NET:
- Eventuale moduli HTTP registrati nel runtime di ASP.NET non potrebbero mai accedere alla richiesta WCF a meno di aver intercettato un evento che precede PostAuthenticateRequest;
- Il servizio WCF non ha accesso all’oggetto HttpContext di ASP.NET nemmeno tramite HttpContext.Current;
- L’eventuale ACL definita sul file .svc a livello dell’applicazione ASP.NET non sarebbe accessibile da WCF ai fini dell’autorizzazione della richiesta;
- Il contenuto della sezione del file web.config che stabilisce le regole ASP.NET di autorizzazione per utenti e ruoli è altresì inaccessibile da WCF;
- Le richieste WCF sono associate all’account di IIS a prescindere dalla configurazione di impersonation di ASP.NET;
Non è affatto detto che queste differenze siano importanti dal punto di vista di un servizio WCF. D’altra parte WCF è una tecnologia progettata per essere indipendente dal protocollo di trasmissione e dunque la sua netta indipendenza da ASP.NET non sorprende. (E semmai è ASP.NET ad essere stato progettato in stretta dipendenza da IIS.)
In sostanza, quando è che si ha bisogno del compatibility mode?
Se ne ha bisogno nel momento in cui una qualsiasi delle differenze elencate sopra finisce per limitare il comportamento del servizio WCF. Per esempio, supponiamo che si debba autenticare l’utente prima che questi possa cliccare per inviare una richiesta WCF. (Scenario, questo, assolutamente verosimile e frequente.) L’utente riceve una pagina di login e inserisce le proprie credenziali; se tutto va bene viene generato un cookie e questo cookie viaggia con ogni successiva richiesta. Come fare a risalire all’identità dell’utente dal servizio WCF? Il compatibility mode ci viene in soccorso dal momento che permette la condivisione del contesto della richiesta tra ASP.NET e WCF.
Per attivare il compatibility mode si procede come segue a livello di configurazione dell’host:
<system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> : </system.serviceModel>
In aggiunta, ciascun servizio WCF deve esplicitamente approvare il compatibility mode. Ecco come:
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TimeService : ITimeService
{
:
}
Da notare il fatto che l’attributo AspNetCompatibilityRequirements si applica alla classe del servizio e non al suo contratto. Per default, la proprietà RequirementsMode è impostata a NotAllowed. Se non si cambia questo valore con Allowed oppure Required si riceverà un’eccezione a runtime.
In conclusione, i servizi WCF sono stati pensati per essere indipendenti da binding e trasporto. Attivando il compatibility mode in qualche modo si viola questo principio dal momento che si accoppia il servizio con il protocollo HTTP e l’host IIS. D’altra parte un servizio WCF che riceve richieste da un AJAX layer è con ogni probabilità un servizio che esiste solo per quella ragione. E dunque vederlo funzionare in compatibility mode è persino una scelta naturale.


Commenti