Gestione delle eccezioni in WCF

Le eccezioni sono errori che si verificano in fase di esecuzione; la gestione delle eccezioni è la tecnica per gestire questi errori di runtime. In genere si utilizzano blocchi try, catch e infine (noti anche come blocchi di eccezioni) nel codice dell'applicazione per gestire le eccezioni. Se le eccezioni non vengono gestite correttamente nel codice dell'applicazione e si è verificata un'eccezione in fase di runtime, l'esecuzione dell'applicazione verrebbe interrotta.

La gestione delle eccezioni in WCF non è così semplice: sei costretto a inviare oggetti .Net in rete e il tuo servizio WCF può inviare solo dati serializzati, ad esempio messaggi SOAP al client. Puoi gestire le eccezioni in WCF in uno di questi tre modi:

  1. Utilizzo di FaultException
  2. Utilizzando IErrorHandler
  3. Utilizzo di returnUnknownExceptionsAsFaults

In questo post presenterò una discussione sui vari modi in cui i messaggi di eccezione possono essere trasmessi dal servizio WCF ai consumatori del servizio.

Considera questo semplice servizio WCF.

[Contratto di servizio]

interfaccia pubblica IDBManagerService

    {

        [OperationContract]

        void Save (Employee emp);

    }

Il contratto di servizio IDBManagerService contiene un contratto di operazione per rendere persistente un oggetto dipendente nel database.

classe pubblica DBManagerService: IDBManagerService

    {

        void Save (Employee emp)

        {

         provare

           {

            // Codice per memorizzare un oggetto dipendente nel database

           }

           cattura (eccezione ex)

           {

               lancia una nuova eccezione ("Errore durante il salvataggio dei dati ...");

           }

        }

    }

Supponiamo ora che si sia verificato un errore durante la connessione al database o la memorizzazione dell'oggetto dipendente nel database nel momento in cui si tenta di utilizzare il servizio. Riceverai quindi un'eccezione con questo messaggio: "System.ServiceModel.FaultException: il server non è stato in grado di elaborare la richiesta a causa di un errore interno. Per ulteriori informazioni sull'errore, attiva IncludeExceptionDetailInFaults (da ServiceBehaviorAttribute o dalla configurazione comportamento) sul server per inviare le informazioni sull'eccezione al client oppure attivare la traccia come da documentazione dell'SDK di Microsoft .Net Framework 3.0 e controllare i log di traccia del server. "

È possibile utilizzare impostare l'elemento includeExceptionDetailInFaults su true nel file web.config in modo che i dettagli aggiuntivi dell'eccezione siano inclusi nell'errore per rendere più conveniente controllare cosa è andato storto.

Puoi anche farlo scrivendo codice. Di seguito è riportato uno snippet di codice che illustra come impostare questa proprietà su true.

    typeof (ServiceDebugBehavior));

    nuovo ServiceDebugBehavior {IncludeExceptionDetailInFaults = true});

Puoi anche impostarlo su true utilizzando il tag ServiceBehavior come mostrato di seguito.

[ServiceBehavior (IncludeExceptionDetailInFaults = true)]

classe pubblica DBManagerService: IDBManagerService

{

}

Quando si tenta di utilizzare nuovamente il servizio, verrà visualizzato un messaggio di eccezione più preciso.

Utilizzo di FaultException

Tuttavia, se è necessario passare messaggi di eccezione di facile utilizzo dal servizio, è necessario generare eccezioni di errore. Le eccezioni di errore sono eccezioni che vengono generate da un servizio WCF quando si verifica un'eccezione in fase di esecuzione: tali eccezioni vengono in genere utilizzate per trasmettere dati di errore non tipizzati ai consumatori del servizio. È possibile gestire le eccezioni nei metodi di servizio più o meno allo stesso modo di altri metodi e quindi trasformarle in eccezioni di errore.

Lo snippet di codice seguente mostra il metodo di servizio aggiornato: il metodo di servizio ora genera un'eccezione di errore.

classe pubblica DBManagerService: IDBManagerService

    {

        void Save (Employee emp)

        {

            provare

            {

               // Codice per memorizzare un oggetto dipendente nel database

            }

            cattura (eccezione ex)

            {

               lancia una nuova FaultException ("Errore durante il salvataggio dei dati ...");

            }

        }

    }

È ora necessario gestire l'eccezione di errore nel codice quando si utilizza questo servizio. Puoi saperne di più sulle eccezioni di errore in WCF da questo articolo di MSDN.

È inoltre possibile creare una classe di errore personalizzata contrassegnata con l'attributo DataContract.

[DataContract]

classe pubblica CustomFault

{

[DataMember]

stringa pubblica Fonte;

[DataMember]

stringa pubblica ExceptionMessage;

[DataMember]

stringa pubblica InnerException;

[DataMember]

stringa pubblica StackTrace;

}

Il frammento di codice seguente illustra come utilizzare la classe CustomFault per generare un'eccezione FaultException fortemente tipizzata.

void Save (Employee emp)

{

provare

{

  // Codice per salvare l'oggetto dipendente nel database

}

cattura (eccezione ex)

{

CustomFault cx = new CustomFault ();

lancia una nuova FaultException (ex, new FaultReason ("Questa è un'eccezione di errore fortemente tipizzata"));

}

}

Dovresti anche specificare l'attributo FaultContract sul metodo di servizio che genererebbe FaultException. Il metodo di salvataggio modificato sarebbe simile a questo.

[Contratto di servizio]

interfaccia pubblica IDBManagerService

    {

        [OperationContract]

        [FaultContract]

        void Save (Employee emp);

    }

Utilizzo di returnUnknownExceptionsAsFaults

È possibile utilizzare l'attributo returnUnknownExceptionsAsFaults nella configurazione del comportamento del servizio per generare automaticamente un'eccezione come errore SOAP. Il frammento di codice seguente illustra come ottenere questo risultato.

                 returnUnknownExceptionsAsFaults = "True">

Gestire le eccezioni a livello globale

Un altro modo per gestire le eccezioni in WCF consiste nell'implementare l'interfaccia IErrorHandler sulla classe del servizio per gestire tutte le eccezioni a livello globale e fornire un'eccezione FaultException conforme a SOAP. Questa interfaccia contiene due metodi: HandleError e ProvideFault. Mentre il primo viene utilizzato per eseguire alcune attività con l'errore, il secondo viene utilizzato per restituire un messaggio di errore. Tieni presente che puoi anche configurare IErrorHandler (attivarlo o disattivarlo) nel file configurabile del servizio.