I miei due centesimi sui contratti in WCF

WCF (Windows Communication Foundation) è una piattaforma di messaggistica sicura, affidabile e scalabile per lo sviluppo di servizi in .Net. Quando si lavora con WCF, è prima necessario creare un contratto di servizio e quindi definire le operazioni di servizio oi contratti di operazione in esso. Esistono molti tipi diversi di contratti in WCF: contratti di servizio, contratti dati, contratti di errore, contratti di messaggio e contratti di operazione.

I servizi WCF espongono i contratti per facilitare la comunicazione con i consumatori del servizio. Un contratto è uno standard utilizzato in WCF per specificare cosa dovrebbe fare il servizio. I contratti in WCF possono essere classificati in due categorie distinte:

  •  Contratti comportamentali: in WCF possiamo avere tre contratti comportamentali, ovvero ServiceContract, OperationContract e FaultContract.
  • Contratti strutturali: includono DataContract e MessageContract.

ServiceContracts e OperationContracts

Un ServiceContract viene utilizzato per indicare le operazioni del servizio disponibili per il consumatore del servizio in un particolare endpoint del servizio. In sostanza, il ServiceContract viene utilizzato per specificare le operazioni che sono disponibili per il client del servizio da utilizzare. Un ServiceContract viene definito utilizzando l'attributo ServiceContract, solitamente applicato a un'interfaccia.

Un ServiceContract può definire il modello di scambio di messaggi tra il fornitore di servizi e l'utente del servizio e può avere una o più operazioni di servizio; questi sono noti come contratti di operazione. Un contratto di operazione viene utilizzato per definire la firma del metodo di servizio e anche il flusso di transazione, la direzione dell'operazione di servizio e anche i contratti di errore che possono essere associati.

L'elenco di codice fornito di seguito illustra come viene definito un tipico contratto di servizio.

[ServiceContract]

interface ITestService

{

     [OperationContract]

     string GetMessage();

}

public class TestService  :  ITestService

{

     public string GetMessage()

      {

           return "Hello World!";

      }

}

Nell'elenco di codici mostrato sopra, l'unico contratto di operazione nel contratto di servizio è GetMessage. Nota come sono stati specificati gli attributi. Inoltre, se nel contratto di servizio è presente un metodo per il quale non è impostato l'attributo del contratto di operazione, il metodo non può essere esposto dal servizio, ovvero il metodo non può essere utilizzato dal consumatore del servizio.

DataContracts, MessageContracts e FaultContracts

Un DataContract viene utilizzato per descrivere i dati che devono essere scambiati in rete. Viene utilizzato per specificare come i dati possono essere scambiati tra il fornitore del servizio e il consumatore del servizio. È possibile utilizzare l'attributo [DataContract] per decorare il tipo in modo che i dati possano essere serializzati prima di essere passati in rete. Quando si definiscono i contratti dati, in genere è necessario utilizzare membri dati per definire le proprietà del contratto dati.

Il frammento di codice seguente mostra come decorare una classe con l'attributo [DataContract].

[DataContract]

public class Employee

{

 [DataMember]

 public string ID;

 [DataMember]

 public string FirstName;

 [DataMember]

 public string LastName;

}

Un contratto di messaggio è uno che può essere utilizzato per decorare il corpo di un messaggio in WCF. Nella maggior parte dei casi non è necessario utilizzare i contratti di messaggio: l'utilizzo dei contratti dati sarebbe sufficiente. Se hai bisogno di un controllo granulare sui tuoi messaggi SOAP, puoi sfruttare i contratti di messaggio. È possibile utilizzare i contratti di messaggio per accedere alle intestazioni SOAP.

È possibile utilizzare i contratti di messaggio per specificare il formato del messaggio SOAP che deve essere richiesto. Sebbene MessageHeaderAttribute possa essere applicato ai membri che si desidera includere nelle intestazioni SOAP, MessageBodyMemberAttribute può essere utilizzato per definire i membri che dovrebbero far parte del corpo del messaggio SOAP.

È possibile definire un contratto di messaggio applicando MessageContractAttribute come mostrato di seguito.

[MessageContract]

public class Transaction

{

  [MessageHeader] public DateTime date;

  [MessageBodyMember] public int amount;

}

Un contratto di errore in WCF viene utilizzato per definire e propagare gli errori che possono verificarsi quando viene eseguita un'operazione di servizio. In sostanza, puoi sfruttare i contratti di errore per trasmettere i messaggi di errore al consumatore del servizio quando si verifica un errore nel tuo servizio. Si noti che è possibile decorare i contratti di operazione utilizzando un contratto di errore: un contratto di operazione di servizio può avere uno o più contratti di errore associati. Ecco un esempio che mostra come è possibile utilizzare i contratti di errore. Si noti che due contratti di errore denominati FaultContractOne e FaultContractTwo sono stati applicati al contratto di operazione Contratto nell'esempio di codice riportato di seguito.

[ServiceContract]

interface Contract

{

 [FaultContract(typeof(FaultContractOne))]

 [FaultContract(typeof(FaultContractTwo))]

 [OperationContract]

 string GetMessage();

 }