I servizi esposti con WCF (come i Web Service in genere) non usano le eccezioni standard, ma devono usare dei messaggi particolare per notificare gli errori. Per rendere il sistema di notifica degli errori assimilabile alla gestione delle eccezioni standard il namespace System.ServiceModel mette a disposizione una eccezione, FaultException, che rappresenta un messagio fault di SOAP.
FaultException mette a disposizione una serie di proprietà che permettono già di specificare una serire di informazioni relativi all'eccezione sollevata, come il FaultCode e la FaultReason.
Nel caso si volesse scambiare una serie di informazioni aggiuntive, specifiche della nostra applicazione, ci viene incontro la versione generica della stessa eccezione. In questo caso specifichiamo come tipo generico il tipo di classe che vogliamo scambiare: è sufficiente che la classe che vogliamo utilizzare sia un DataContract e che gli OperationContract che sollevano quelle eccezioni siano decorati coll'attributo FaultContract specificando il tipo della classe.
Vediamo un esempio che vale più di mille parole:
definisco il tipo di dato che voglio scambiare con le eccezioni
[DataContract]
public sealed class MyExceptionData
{
[DataMember]
public string MyProperty { get; set; }
}
definisco quindi il mio servizio
[ServiceContract]
public interface IMyService
{
[OperationContract]
[FaultContract(typeof(MyExceptionData))]
void MyOperation();
}
e una implementazione
public class MyService : IMyService
{
#region IMyService Members
public void MyOperation()
{
MyExceptionData data = new MyExceptionData()
{
MyProperty = "MyData"
};
throw new FaultException<MyExceptionData>(data);
}
#endregion
}
Ecco quindi come si può comportare il consumatore del servizio:
try
{
MyServiceClient service = new MyServiceClient();
service.MyOperation();
}
catch (FaultException<MyExceptionData> e)
{
//la proprietà detail è di tipo generico e contiene MyExceptionData
Console.WriteLine(e.Detail.MyProperty);
}
Matteo