Gestione delle eccezioni in Windows Communication Foundation

4 pagine in totale: <<Indietro 1 [2] 3 4 Avanti >>

Fault Contracts

Non tutti gli errori generati sul server devono causare la chiusura del canale di comunicazione con il client. Ad esempio, la mancanza o l'erroneità di un parametro devono essere gestiti in maniera concordata in quanto non si tratta di eccezioni inaspettate, bensì di normali controlli che evitano che il messaggio inviato dal client al server sia errato. In questi casi, il server deve sollevare un'eccezione che il client deve intercettare senza chiudere la comunicazione e quindi occorre stipulare un contratto per determinate eccezioni/metodi. Questo contratto prende il nome di FaultContract.

[FaultContract(typeof(ArgumentException)]
public void GetCustomerById(int id){
  if (id < 1){
    throw new FaultException<ArgumentException>(new ArgumentException("L'id deve essere maggiore di zero"), "Informazioni aggiuntive");
  }
  ...
}

Come si vede nello snippet, il servizio dichiara che il metodo GetCustomerById può sollevare l'eccezione FaultException. Se il client che chiama il metodo passa 0 come parametro, il server solleva una FaultException e la ripassa al client.

Ma come può il client essere a conoscenza del FaultContract? La risposta è semplice: il FaultContract è pubblicato nei metadati e quindi in fase di generazione del codice del proxy i contratti vengono caricati cosi che il client è in grado di gestire tutto senza problemi.

ServiceProxy proxy = new ServiceProxy();
try{
  proxy.GetCustomerById(0)
}
catch(FaultException<ArgumentException> ex){
  Console.WriteLine("Codice cliente errato");
}
catch (Exception ex){
  Console.WriteLine ("Errore generico");
}

Il risultato del codice client è la scrittura sulla console del messaggio "Codice cliente errato". Se non ci fosse stato il FaultContract, il client avrebbe ricevuto una FaultException generica e non avrebbe potuto gestire diversamente gli errori tra loro. In questo modo, il primo dei tre paradigmi illustrati sopra è perfettamente rispettato perché una CommunicationException o una Fault non riportano al client i motivi dell'errore, mentre una FaultException generica riporta solo ciò che è stabilito a priori.

Nonostante questo pattern sia in assoluto il più corretto, in fase di sviluppo torna sicuramente comodo il fatto che il client possa ricevere i dati completi dell'errore, anche se questi non fanno parte del contratto stabilito. In questo caso, bisogna configurare un behavior per il servizio ed impostarne la proprietà includeExceptionDetailsinFaults a "true". Quest'operazione può essere fatta sia in fase di configurazione che da codice; ovviamente, la prima opzione è preferibile in quanto si può passare da una fase di testing ad una di deploy, senza dover modificare e quindi ricompilare l'applicazione.

Modalità imperativa

[ServiceBehavior(IncludeExceptionDetailsInFaults=true)]
class Service : IContract{
...
}

Modalita dichiarativa

<system.servicemodel>
  <services>
    <service name="Service" behaviorConfiguration="testingEnvironment">
      ...
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
       <behavior name="testingEnvironment">
        <serviceDebug includeExceptionDetailsInFaults="true"/>
    </serviceBehaviors>
  </behaviors>

Gestione dell'eccezione sul server

La seconda regola fondamentale nella gestione delle eccezioni è il logging per fini di gestione e manutenzione del servizio. Anche in questo caso WCF viene in aiuto dello sviluppatore grazie ad un meccanismo di estensibilità molto potente che permette non solo di eseguire logging, ma anche di eseguire controlli dell'ultimo minuto sull'eccezione che viene propagata al client ed apportare eventuali modifiche.

La prima cosa da fare è creare la classe responsabile di questa gestione. Questa classe deve obbligatoriamente implementare l'interfaccia IErrorHandler per essere inserita nella pipeline di WCF. Volendo, si può anche decidere di utilizzare la classe solo per alcuni dispatcher del servizio, ma nella maggior parte dei casi questo non serve, quindi si può utilizzare la classe per gestire gli errori dell'intero servizio.

L'intefaccia IErrorHandler ha due metodi: ProvideFault e HandleError.

4 pagine in totale: <<Indietro 1 [2] 3 4 Avanti >>

Contenuti dell'articolo

Commenti
Dai un voto a questo articolo, ci aiuterà a migliorare il nostro sito (1 è il voto minimo, 5 il massimo).

Per procedere al rating dell'articolo devi essere autenticato.
simone_b scrive:
lunedì 28 gennaio 2008 | 1 risposta

Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.



TUTORIALS


IN EVIDENZA
MISC