4 pagine in totale: <<Indietro 1 2 [3] 4 Avanti >>
ProvideFault
Il metodo ProvideFault è l'ultimo metodo invocato immediatamente prima che l'eccezione venga inviata al client di qualunque tipo essa sia. Infatti, sia che si tratti di una FaultException che fa parte di un contratto, di un errore non gestito o di qualunque altro tipo di eccezione, questo metodo viene comunque invocato. Questo metodo viene utilizzato, come detto sopra, per modificare all'ultimo momento l'eccezione da propagare al client. Per chiarire il perché di questa esigenza è bene fare un esempio.
La firma di ProvideFault è:
- Exception error: l'eccezione sollevata;
- MessageVersion version: versione del messaggio;
- Message fault: messaggio che il metodo restituisce.
Molto spesso, l'accesso ai dati non viene effettuato in maniera diretta dal servizio, ma c'è un'assembly che viene utilizzato per lo scopo. Questo assembly può essere utilizzato dal servizio, ma anche da altre applicazioni che possono essere un sito web così come una applicazione winform. Ovviamente, un assembly studiato per questi scopi non può essere legato a WCF e quindi, se c'è un'eccezione, non si deve restituire una FaultException, bensì una classica Exception. Questo significa che per ogni metodo del servizio si deve utilizzare un try/catch con tanti blocchi catch quante sono le eccezioni nel FaultContract del metodo ed in ogni blocco bisogna wrappare l'eccezione in una FaultException
Senza scomodare troppo la reflection e lo StackTtrace si può ottenere comunque qualcosa del genere; per prima cosa, bisogna istanziare un oggetto FaultException passando in input l'eccezione ricevuta dai parametri in input al metodo. Una volta ottenuto un riferimento alla FaultException, si deve usare il metodo CreateMessageFault per generare il messaggio modificato che si vuole spedire al client. L'ultimo step consiste nel wrappare il messaggio di fault, tramite il metodo statico CreateMessage della classe Message, nella medesima ed assegnare questo nuovo oggetto alla variabile fault passata per riferimento in input al metodo che la userà all'esterno per spedire tutto al client.
public void ProvideFault(Exception error, MessageVersion version, ref Message fault){
if (error is NullReferenceException){
FaultException<NullReferenceException> faultEx = new FaultException<NullReferenceException>(new
NullReferenceException(error.Message));
MessageFault messageFault = faultEx.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, faultEx.Action);
}
}
Come si vede dallo snippet, questa tecnica non salva dallo scrivere un po' di codice per testare i vari tipi di errore dei contratti previsti dall'applicazione; tuttavia, questo codice va inserito solo nella classe di gestione delle eccezioni lasciando puliti tutti i metodi del servizio quindi si ha in ogni caso un grande risparmio di codice.
Un'ultima nota va spesa per sottolineare un fatto: essendo il metodo ProvideFault eseguito prima di inviare l'eccezione al client, non si devono eseguire lunghe operazioni in questo metodo (come il logging), poiché bloccherebbero l'esecuzione dell'intera chiamata al servizio. Per questi scopi è disponibile il secondo metodo dell'interfaccia IErrorHandler: HandleError.
HandleError
Il metodo HandleError è stato appositamente studiato per effettuare tutte quelle operazioni inerenti ad un errore che però non necessitano di bloccare la chiamata al servizio finché non sono eseguite. Ciò è possibile grazie al fatto che il thread in cui questo metodo viene invocato è diverso da quello in cui il codice del metodo viene eseguito.
La firma del metodo HandleError è la seguente:
Exception error: rappresenta l'eccezione sollevata dal servizio.
Poiché si possono aggiungere più classi alla gestione delle eccezioni, HandleError ritorna un booleano che specifica se la classe seguente nella lista deve essere utilizzata oppure no. Nel caso si ritorni "true", l'esecuzione viene arrestata all'oggetto attuale, altrimenti si WCF va avanti nella catena.
public bool HandleError(Exception error){
LogService.LogException(error);
return false;
} E' importante notare una cosa: oltre che ad essere invocato su un altro thread, il metodo HandleError viene probabilmente invocato successivamente al momento in cui l'eccezione viene spedita al client. Questo significa che qualunque cosa succeda nel metodo, questo non ha alcun effetto sul codice che ha scatenato l'eccezione, ne sul client.
4 pagine in totale: <<Indietro 1 2 [3] 4 Avanti >>
Contenuti dell'articolo
Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.





Difficoltà
Stampa
Download 


10annidi.ASPItalia.com: iscriviti alla competizione e vinci fantastici premi ogni mese!

Complimenti Stefano, gran bell'articolo. Grazie!
Continua »»» | Rispondi »»»