Panoramica dei client WCF

Contenuto della sezione vengono descritte le operazioni svolte delle applicazioni client e vengono fornite istruzioni su come configurare, creare e usare un client Windows Communication Foundation (WCF), nonché su come proteggere le applicazioni client.

Uso di oggetti client WCF

Un'applicazione client è un'applicazione gestita che usa un client WCF per comunicare con un'altra applicazione. Per creare un'applicazione client per un servizio WCF è necessario eseguire i passaggi seguenti:

  1. Ottenere le informazioni relative al contratto di servizio, alle associazioni e all'indirizzo per un endpoint di servizio.

  2. Creare un client WCF usando queste informazioni.

  3. Chiamare le operazioni.

  4. Chiudere l'oggetto client WCF.

Nelle sezioni seguenti vengono illustrate queste procedure e vengono fornite informazioni introduttive sugli argomenti seguenti:

  • Gestione degli errori,

  • Configurazione e protezione dei client.

  • Creazione di oggetti di callback per i servizi duplex.

  • Chiamate ai servizi in modo asincrono.

  • Chiamate ai servizi mediante canali client.

Ottenere informazioni sul contratto di servizio, sulle associazioni e sugli indirizzi

In WCF servizi e client modellano i contratti usando attributi, interfacce e metodi gestiti. Per eseguire la connessione a un servizio in un'applicazione client è necessario ottenere le informazioni sul tipo per il contratto di servizio. In genere, si ottengono informazioni sul tipo per il contratto di servizio usando lo strumento ServiceModel Metadata Utility Tool (Svcutil.exe). L'utilità scarica metadati dal servizio, li converte in un file di codice sorgente gestito nel linguaggio desiderato e crea un file di configurazione dell'applicazione client che può essere usato per configurare l'oggetto client WCF. Ad esempio, se si intende creare un oggetto client WCF per richiamare un MyCalculatorService e i metadati per questo servizio sono pubblicati in http://computerName/MyCalculatorService/Service.svc?wsdl, l'esempio di codice seguente mostra come usare Svcutil.exe per ottenere un file ClientCode.vb che contenga il contratto di servizio nel codice gestito.

svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/MyCalculatorService/Service.svc?wsdl  

È possibile compilare questo codice di contratto nell'applicazione client o in un altro assembly che l'applicazione client potrà successivamente usare per creare un oggetto client WCF. Per configurare l'oggetto client per eseguire la connessione al servizio in modo appropriato, è possibile usare il file di configurazione.

Per un esempio di questo processo, vedere Procedura: Creare un client. Per informazioni più complete sui contratti, vedere Contratti.

Creare un oggetto client WCF

Un client WCF è un oggetto locale che rappresenta un servizio di WCF in una forma che il client può usare per comunicare con il servizio remoto. I tipi di client WCF implementano il contratto di servizio di destinazione, pertanto quando se ne crea e configura uno, è possibile usare direttamente l'oggetto client per richiamare le operazioni del servizio. Nella fase di esecuzione WCF converte le chiamate ai metodi in messaggi, invia questi ultimi al servizio, resta in attesa della replica e restituisce questi valori all'oggetto client WCF come valori restituiti o come parametri out o ref.

Per eseguire la connessione ai servizi e usarli è anche possibile usare oggetti del canale client WCF. Per informazioni dettagliate, vedere Architettura client WCF.

Creazione di un nuovo oggetto WCF

Per illustrare l'uso di una classe ClientBase<TChannel>, si supponga che il contratto di servizio seguente sia stato generato da un'applicazione di servizio.

Nota

Se per creare il client WCF si usa Visual Studio, quando al progetto viene aggiunto un riferimento a servizi gli oggetti vengono caricati automaticamente nel Visualizzatore oggetti.

[System.ServiceModel.ServiceContractAttribute(
  Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
    [System.ServiceModel.OperationContractAttribute(
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
      ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
    )]
    [System.ServiceModel.FaultContractAttribute(
      typeof(microsoft.wcf.documentation.SampleFault),
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
    )]
    string SampleMethod(string msg);
}

Se non si usa Visual Studio, esaminare il codice del contratto generato per individuare il tipo che estende la classe ClientBase<TChannel> e l'interfaccia del contratto di servizio ISampleService. In questo caso il tipo ha l'aspetto del codice seguente:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{

    public SampleServiceClient()
    {
    }

    public SampleServiceClient(string endpointConfigurationName)
        :
            base(endpointConfigurationName)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, string remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(binding, remoteAddress)
    {
    }
    public string SampleMethod(string msg)
    {
        return base.Channel.SampleMethod(msg);
    }
}

Questa classe può essere creata come un oggetto locale usando uno dei costruttori, configurata e quindi usata per la connessione a un servizio del tipo ISampleService.

È consigliabile creare prima l'oggetto client WCF, quindi usare e chiudere questo oggetto in un singolo blocco Try/Catch. Non usare l'istruzione using (Using in Visual Basic) perché potrebbe mascherare le eccezioni in determinate modalità di errore. Per altre informazioni, vedere le sezioni seguenti, nonché Usare Chiudi e Interrompi per rilasciare le risorse client WCF.

Contratti, associazioni e indirizzi.

Per poter creare un oggetto client WCF, è necessario configurare prima l'oggetto client. L'oggetto client deve avere in particolare un endpoint di servizio da usare. Un endpoint è la combinazione di un contratto di servizio, un'associazione e un indirizzo. Per altre informazioni sugli endpoint, vedere Endpoint: indirizzi, binding e contratti. Queste informazioni si trovano in genere nell'elemento <endpoint> in un file di configurazione di un'applicazione client, ad esempio quello creato dallo strumento Svcutil.exe, e vengono caricate automaticamente quando si crea l'oggetto client. Entrambi i tipi di client WCF dispongono inoltre di overload che consentono di specificare queste informazioni a livello di programmazione.

Ad esempio, un file di configurazione generato per un servizio ISampleService usato negli esempi precedenti contiene le informazioni sull'endpoint riportate di seguito.

<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
                name="WSHttpBinding_ISampleService">
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Questo file di configurazione specifica un endpoint di destinazione nell'elemento <client>. Per altre informazioni sull'uso di più endpoint di destinazione, vedere i costruttori ClientBase<TChannel> o ChannelFactory<TChannel>.

Chiamate alle operazioni

Dopo avere creato e configurato un oggetto client, creare un blocco Try/Catch, chiamare le operazioni nello stesso modo in cui verrebbero chiamate nel caso di un oggetto locale, quindi chiudere l'oggetto client WCF. Quando l'applicazione client chiama la prima operazione, WCF apre automaticamente il canale sottostante e quest'ultimo viene chiuso quando l'oggetto viene riciclato. In alternativa, è possibile aprire e chiudere il canale in modo esplicito prima o dopo la chiamata ad altre operazioni.

Si supponga, ad esempio, di disporre del contratto di servizio seguente:

namespace Microsoft.ServiceModel.Samples  
{  
    using System;  
    using System.ServiceModel;  
  
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]  
    public interface ICalculator  
   {  
        [OperationContract]  
        double Add(double n1, double n2);  
        [OperationContract]  
        double Subtract(double n1, double n2);  
        [OperationContract]  
        double Multiply(double n1, double n2);  
        [OperationContract]  
        double Divide(double n1, double n2);  
    }  
}  
Namespace Microsoft.ServiceModel.Samples  
  
    Imports System  
    Imports System.ServiceModel  
  
    <ServiceContract(Namespace:= _  
    "http://Microsoft.ServiceModel.Samples")> _
   Public Interface ICalculator  
        <OperationContract> _
        Function Add(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
        Function Subtract(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
        Function Multiply(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
     Function Divide(n1 As Double, n2 As Double) As Double  
End Interface  

È possibile chiamare operazioni creando un oggetto client WCF e chiamando i relativi metodi, come illustrato nell'esempio di codice seguente. L'apertura, la chiamata e la chiusura dell'oggetto client WCF si verificano all'interno di un singolo blocco Try/Catch. Per altre informazioni, vedere Accesso ai servizi tramite un client WCF e Utilizzo di Chiudi e Interrompi per rilasciare le risorse client WCF.

CalculatorClient wcfClient = new CalculatorClient();
try
{
    Console.WriteLine(wcfClient.Add(4, 6));
    wcfClient.Close();
}
catch (TimeoutException timeout)
{
    // Handle the timeout exception.
    wcfClient.Abort();
}
catch (CommunicationException commException)
{
    // Handle the communication exception.
    wcfClient.Abort();
}

Gestione degli errori

In un'applicazione client possono verificarsi eccezioni quando si apre il canale client sottostante (sia in modo esplicito che automaticamente chiamando un'operazione), quando si usa l'oggetto client o l'oggetto canale per chiamare operazioni o quando si chiude il canale client sottostante. Oltre a gestire qualsiasi oggetto System.TimeoutException generato come risultato di errori SOAP restituiti dalle operazioni, le applicazioni dovrebbero essere configurate per gestire almeno possibili eccezioni System.ServiceModel.CommunicationException e System.ServiceModel.FaultException. Gli errori SOAP specificati nel contratto dell'operazione vengono generati nelle applicazioni client come oggetto System.ServiceModel.FaultException<TDetail> dove il parametro di tipo è il tipo di dettaglio dell'errore SOAP. Per altre informazioni sulla gestione delle condizioni di errore in un'applicazione client, vedere Errori di invio e ricezione. Per un esempio completo che mostra come gestire gli errori in un client, vedere Eccezioni previste.

Configurazione e protezione dei client

La configurazione di un client inizia con il caricamento obbligatorio di informazioni sull'endpoint di destinazione per il client o per l'oggetto del canale, generalmente da un file di configurazione, sebbene sia possibile caricare queste informazioni anche a livello di programmazione usando i costruttori e le proprietà del client. Per attivare determinati comportamenti del client e per numerosi scenari di sicurezza sono tuttavia necessarie operazioni di configurazione aggiuntive.

I requisiti di sicurezza per i contratti di servizio, ad esempio, vengono dichiarati nell'interfaccia del contratto di servizio e se lo strumento Svcutil.exe ha creato un file di configurazione, questo file contiene in genere un'associazione in grado di supportare i requisiti di sicurezza del servizio. In alcuni casi può essere però necessaria un'ulteriore configurazione della protezione, ad esempio la configurazione di credenziali client. Per informazioni complete sulla configurazione della sicurezza per i client WCF, vedere Protezione dei client.

Nelle applicazioni client possono essere inoltre abilitate alcune modifiche personalizzate, ad esempio comportamenti personalizzati nella fase di esecuzione. Per altre informazioni su come configurare un comportamento client personalizzato, vedere Configurazione dei comportamenti del client.

Creazione di oggetti di callback per i servizi duplex

I servizi duplex specificano un contratto di callback che l'applicazione client deve implementare per fornire un oggetto di callback affinché il servizio esegua la chiamata in base ai requisiti del contratto. Sebbene gli oggetti di callback non siano servizi completi (ad esempio, non è possibile avviare un canale con un oggetto di callback), ai fini dell'implementazione e della configurazione possono essere considerati come una specie di servizio.

I client di servizi duplex devono:

  • Implementare una classe di contratto di callback.

  • Creare un'istanza della classe di implementazione del contratto di callback e usarla per creare l'oggetto System.ServiceModel.InstanceContext che viene passato al costruttore client WCF.

  • Richiamare operazioni e gestire callback di operazioni.

Gli oggetti client duplex di WCF funzionano come le relative controparti non duplex, tranne per il fatto che espongono la funzionalità necessaria per supportare i callback, inclusa la configurazione del servizio di callback.

È possibile controllare, ad esempio, i vari aspetti del comportamento degli oggetti di callback in fase di esecuzione usando proprietà dell'attributo System.ServiceModel.CallbackBehaviorAttribute nella classe di callback. Un altro esempio è l'uso della classe System.ServiceModel.Description.CallbackDebugBehavior per attivare la restituzione di informazioni sull'eccezione ai servizi che chiamano l'oggetto di callback. Per altre informazioni, vedere Servizi duplex. Per un esempio completo, vedere Duplex.

Nei computer Windows XP che eseguono Internet Information Services (IIS) 5.1, i client duplex devono specificare un indirizzo client di base usando la classe System.ServiceModel.WSDualHttpBinding. In caso contrario verrà generata un'eccezione. Nel codice di esempio seguente viene illustrato come eseguire questa procedura nel codice.

WSDualHttpBinding dualBinding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
dualBinding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");

Dim dualBinding As New WSDualHttpBinding()
Dim endptadr As New EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server")
dualBinding.ClientBaseAddress = New Uri("http://localhost:8000/DuplexTestUsingCode/Client/")

Il codice seguente mostra come eseguire la procedura in un file di configurazione.

<client>
  <endpoint
    name ="ServerEndpoint"
    address="http://localhost:12000/DuplexUsingConfig/Server"
    bindingConfiguration="WSDualHttpBinding_IDuplex"
    binding="wsDualHttpBinding"
    contract="IDuplex"
/>
</client>
<bindings>
  <wsDualHttpBinding>
    <binding
      name="WSDualHttpBinding_IDuplex"
      clientBaseAddress="http://localhost:8000/myClient/"
    />
  </wsDualHttpBinding>
</bindings>

Chiamate ai servizi in modo asincrono

La modalità in cui vengono chiamate le operazioni dipende interamente dallo sviluppatore client. Ciò è dovuto al fatto che i messaggi che costituiscono un'operazione possono essere mappati a metodi sincroni o asincroni quando vengono espressi in codice gestito. Pertanto, se si desidera compilare un client che chiama operazioni in modo asincrono, è possibile usare Svcutil.exe per generare codice client asincrono usando l'opzione /async. Per altre informazioni, vedere Procedura: Chiamare operazioni del servizio in modo asincrono.

Chiamate ai servizi mediante canali client di WCF

I tipi di client WCF estendono la classe ClientBase<TChannel>, che deriva essa stessa dall'interfaccia System.ServiceModel.IClientChannel per esporre il sistema di canali sottostante. È possibile richiamare servizi usando il contratto di servizio di destinazione con la classe System.ServiceModel.ChannelFactory<TChannel>. Per informazioni dettagliate, vedere Architettura client WCF.

Vedi anche