Übersicht über den WCF-Client

In diesem Abschnitt wird beschrieben, was Clientanwendungen tun, wie Sie einen Windows Communication Foundation (WCF)-Client konfigurieren, erstellen und verwenden und wie Sie Clientanwendungen sichern.

Verwenden von WCF-Clientobjekten

Eine Clientanwendung ist eine verwaltete Anwendung, die einen WCF-Client verwendet, um mit einer anderen Anwendung zu kommunizieren. Das Erstellen einer Clientanwendung für einen WCF-Dienst erfordert die folgenden Schritte:

  1. Abrufen des Dienstvertrags, der Bindungen und der Adressinformationen für einen Dienstendpunkt.

  2. Erstellen Sie einen WCF-Client mithilfe dieser Informationen.

  3. Aufrufen von Vorgängen.

  4. Schließen Sie das WCF-Clientobjekt.

In den folgenden Abschnitten finden Sie eine Erläuterung dieser Schritte und kurze Einführungen in die folgenden Probleme:

  • Behandeln von Fehlern

  • Konfigurieren und Sichern von Clients.

  • Erstellen von Rückrufobjekten für Duplexdienste

  • Asynchrones Aufrufen von Diensten.

  • Aufrufen von Diensten mithilfe von Clientkanälen.

Abrufen von Dienstvertrag, Bindungen und Adressen

In WCF modellieren Dienste und Clients Verträge mithilfe verwalteter Attribute, Schnittstellen und Methoden. Soll eine Verbindung zu einem Dienst in einer Clientanwendung hergestellt werden, muss der Informationstyp für den Dienstvertrag abgerufen werden. In der Regel erhalten Sie Typinformationen für den Dienstvertrag mithilfe des ServiceModel Metadata Utility Tools (Svcutil.exe). Das Dienstprogramm lädt Metadaten vom Dienst herunter, konvertiert sie in eine verwaltete Quellcodedatei in der Sprache Ihrer Wahl und erstellt eine Clientanwendungskonfigurationsdatei, die Sie zum Konfigurieren Ihres WCF-Clientobjekts verwenden können. Falls Sie beispielsweise ein -Clientobjekt erstellen, um MyCalculatorService aufzurufen und wissen, dass die Metadaten für diesen Dienst unter http://computerName/MyCalculatorService/Service.svc?wsdl veröffentlicht werden, wird im folgenden Codebeispiel die Verwendung von Svcutil.exe zum Abrufen einer Datei vom Typ ClientCode.vb gezeigt, die den Dienstvertrag in verwaltetem Code beinhaltet.

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

Sie können diesen Vertragscode entweder in die Clientanwendung oder in eine andere Assembly kompilieren, die die Clientanwendung dann zum Erstellen eines WCF-Clientobjekts verwenden kann. Sie können die Konfigurationsdatei zum Konfigurieren des Clientobjekts verwenden, um eine ordnungsgemäße Verbindung zum Dienst herzustellen.

Ein Beispiel für diesen Prozess finden Sie unter Vorgehensweise: Erstellen eines Clients. Ausführlichere Informationen zu Verträgen finden Sie unter Verträge.

Erstellen eines WCF-Clientobjekts

Ein WCF-Client ist ein lokales Objekt, das einen WCF-Dienst in einer Form darstellt, die der Client zur Kommunikation mit dem Remotedienst verwenden kann. WCF-Clienttypen implementieren den Zieldienstvertrag. Wenn Sie also einen erstellen und konfigurieren, können Sie das Clientobjekt direkt verwenden, um Dienstvorgänge aufzurufen. Die WCF-Laufzeit konvertiert die Methodenaufrufe in Nachrichten, sendet diese anschließend an den Dienst, hört die Antwort ab und gibt diese Werte an das WCF-Clientobjekt als Rückgabewerte oder als out-Parameter bzw. ref-Parameter zurück.

Sie können auch WCF-Clientkanalobjekte verwenden, um eine Verbindung mit Diensten herzustellen und diese zu verwenden. Ausführliche Informationen finden Sie unter WCF-Clientarchitektur.

Erstellen eines neuen WCF-Objekts

Wenn Sie die Verwendung einer ClientBase<TChannel>-Klasse darstellen möchten, nehmen Sie an, dass der folgende einfache Dienstvertrag von einer Dienstanwendung generiert wurde.

Hinweis

Wenn Sie Visual Studio zum Erstellen Ihres WCF-Clients verwenden, werden Objekte automatisch in den Objektbrowser geladen, wenn Sie Ihrem Projekt einen Dienstverweis hinzufügen.

[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);
}

Wird Visual Studio nicht verwendet, prüfen Sie den generierten Vertragscode, um den Typ zu suchen, durch den ClientBase<TChannel> und die Dienstvertragsschnittstelle ISampleService erweitert werden. In diesem Fall entspricht der Typ dem folgenden Code:

[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);
    }
}

Diese Klasse kann als lokales Objekt mithilfe eines der Konstruktoren erstellt, konfiguriert und anschließend zum Herstellen einer Verbindung zu einem Dienst vom Typ ISampleService verwendet werden.

Es wird empfohlen, zuerst das WCF-Clientobjekt zu erstellen, es anschließend zu verwenden und in einem einzelnen try/catch-Block zu schließen. Verwenden Sie die using-Anweisung (Using in Visual Basic) nicht, da sie Ausnahmen in bestimmten Fehlermodi maskieren kann. Weitere Informationen finden Sie in den folgenden Abschnitten sowie Schließen und Abbrechen zum Freigeben von WCF-Clientressourcen.

Verträge, Bindungen und Adressen

Bevor Sie ein WCF-Clientobjekt erstellen können, müssen Sie das Clientobjekt konfigurieren. Das Objekt benötigt insbesondere einen verwendbaren Dienstendpunkt. Ein Endpunkt ist die Kombination eines Dienstvertrags, einer Bindung und einer Adresse. (Weitere Informationen zu Endpunkten finden Sie unter Endpunkte: Adressen, Bindungen und Verträge.) Diese Informationen befinden sich in der <Regel im Endpunktelement> in einer Clientanwendungskonfigurationsdatei, z. B. das tool Svcutil.exe generiert, und wird automatisch geladen, wenn Sie Ihr Clientobjekt erstellen. Beide WCF-Clienttypen verfügen auch über Überladungen, die das programmgesteuerte Angeben dieser Informationen ermöglichen.

Beispielsweise beinhaltet eine generierte Konfigurationsdatei für einen in den vorherigen Beispielen verwendeten ISampleService die folgenden Endpunktinformationen.

<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>

Mit dieser Konfigurationsdatei wird ein Zielendpunkt im <client>-Element angegeben. Weitere Informationen zur Verwendung mehrerer Zielendpunkte finden Sie in den ClientBase<TChannel> Konstruktoren. ChannelFactory<TChannel>

Aufrufen von Vorgängen

Sobald Sie ein Clientobjekt erstellt und konfiguriert haben, erstellen Sie einen Try/Catch-Block, rufen Sie Vorgänge auf die gleiche Weise auf, wie Sie es tun würden, wenn das Objekt lokal wäre, und schließen Sie das WCF-Clientobjekt. Wenn die Clientanwendung den ersten Vorgang aufruft, öffnet WCF automatisch den zugrunde liegenden Kanal und der zugrunde liegende Kanal wird geschlossen, wenn das Objekt recycelt wird. (Es besteht auch die Möglichkeit, den Kanal vor oder nach dem Aufruf anderer Vorgänge explizit zu öffnen und zu schließen.)

Beispiel: Sie verfügen über den folgenden Dienstvertrag:

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  

Sie können Vorgänge aufrufen, indem Sie ein WCF-Clientobjekt erstellen und seine Methoden aufrufen, wie das folgende Codebeispiel zeigt. Das Öffnen, Aufrufen und Schließen des WCF-Clientobjekts erfolgt innerhalb eines einzigen Try/Catch-Blocks. Weitere Informationen finden Sie unter Zugreifen auf Dienste mithilfe eines WCF-Clients und Schließen und Abbrechen, um WCF-Clientressourcen freizugeben.

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();
}

Behandeln von Fehlern

Ausnahmen können in einer Clientanwendung unter folgenden Bedingungen auftreten: beim Öffnen des zugrunde liegenden Kanals (entweder explizit oder automatisch durch Aufrufen eines Vorgangs), beim Aufrufen von Vorgängen mit dem Client- oder Kanalobjekt oder beim Schließen des zugrunde liegenden Clientkanals. Anwendungen sollten zumindest erwarten, mögliche System.TimeoutException-Ausnahmen und System.ServiceModel.CommunicationException-Ausnahmen sowie jegliche System.ServiceModel.FaultException-Objekte zu behandeln, die infolge von durch Vorgänge zurückgegebenen SOAP-Fehlern ausgelöst werden. Im Vorgangsvertrag angegebene SOAP-Fehler werden als System.ServiceModel.FaultException<TDetail> zu Clientanwendungen heraufgestuft, wobei der Typparameter der Detailtyp des SOAP-Fehlers ist. Weitere Informationen zur Behandlung von Fehlerbedingungen in einer Clientanwendung finden Sie unter Senden und Empfangen von Fehlern. Ein vollständiges Beispiel für das Behandeln von Fehlern in einem Client finden Sie unter Erwartete Ausnahmen.

Konfigurieren und Sichern von Clients

Das Konfigurieren eines Clients beginnt mit dem erforderlichen Laden von Zielendpunktinformationen für das Client- oder Kanalobjekt (in der Regel von einer Konfigurationsdatei), obwohl diese Informationen auch programmgesteuert mithilfe der Clientkonstruktoren und -eigenschaften geladen werden können. Allerdings sind zusätzliche Konfigurationsschritte erforderlich, um ein bestimmtes Clientverhalten zu ermöglichen und zahlreichen Sicherheitsszenarien gerecht zu werden.

Beispielsweise werden Sicherheitsanforderungen für Dienstverträge in der Dienstvertragschnittstelle deklariert, und falls mit „Svcutil.exe“ eine Konfigurationsdatei erstellt wurde, beinhaltet diese Datei normalerweise eine Bindung, die den Sicherheitsanforderungen des Diensts entspricht. In einigen Fällen sind jedoch möglicherweise zusätzliche Sicherheitskonfigurationen erforderlich, zum Beispiel die Konfiguration von Clientanmeldeinformationen. Vollständige Informationen zur Konfiguration der Sicherheit für WCF-Clients finden Sie unter Sichern von Clients.

Zudem können einige benutzerdefinierte Änderungen in Clientanwendungen aktiviert werden, zum Beispiel benutzerdefiniertes Laufzeitverhalten. Weitere Informationen zum Konfigurieren eines benutzerdefinierten Clientverhaltens finden Sie unterKonfigurieren von Clientverhalten.

Erstellen von Rückrufobjekten für Duplexdienste

Mit Duplexdiensten wird ein Rückrufvertrag angegeben, den die Clientanwendung implementieren muss, um gemäß den Vertragsanforderungen ein Rückrufobjekt für den aufzurufenden Dienst bereitzustellen. Obgleich es sich bei Rückrufobjekten nicht um vollständige Dienste handelt (beispielsweise kann ein Kanal nicht mit einem Rückrufobjekt initiiert werden), können Sie zu Implementierungs- und Konfigurationszwecken als eine Art Dienst betrachtet werden.

Clients von Duplexdiensten müssen folgende Vorgänge ausführen:

  • Eine Rückrufvertragsklasse implementieren.

  • Eine Instanz der Implementierungsklasse des Rückrufvertrags erstellen und diese zum Erstellen des System.ServiceModel.InstanceContext-Objekts verwenden, das an den WCF-Clientkonstruktor übergeben wird.

  • Vorgänge aufrufen und Vorgangsrückrufe behandeln.

Duplex-WCF-Clientobjekte funktionieren wie ihre Nicht-Duplex-Gegenstücke, mit der Ausnahme, dass sie die zur Unterstützung von Rückrufen erforderliche Funktionalität bereitstellen, einschließlich der Konfiguration des Rückrufdiensts.

Beispielsweise können verschiedene Aspekte des Laufzeitverhaltens des Rückrufobjekts mithilfe der Eigenschaften des System.ServiceModel.CallbackBehaviorAttribute-Attributs in der Rückrufklasse gesteuert werden. Ein weiteres Beispiel ist die Verwendung der System.ServiceModel.Description.CallbackDebugBehavior-Klasse, um die Rückgabe von Ausnahmeinformationen an Dienste, die das Rückrufobjekt aufrufen, zu ermöglichen. Weitere Informationen finden Sie unter Duplexdienste. Ein vollständiges Beispiel finden Sie unter Duplex.

Auf Windows XP-Computern, auf denen Internetinformationsdienste (IIS) 5.1 ausgeführt wird, muss von Duplexclients eine Clientbasisadresse mithilfe der System.ServiceModel.WSDualHttpBinding-Klasse angegeben werden, da andernfalls eine Ausnahme ausgelöst wird. Im folgenden Codebeispiel wird die entsprechende Umsetzung in Code veranschaulicht.

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/")

Im folgenden Codebeispiel wird die entsprechende Umsetzung in einer Konfigurationsdatei veranschaulicht.

<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>

Asynchrones Aufrufen von Diensten

Die Art und Weise eines Vorgangsaufrufs ist ausschließlich Angelegenheit des Cliententwicklers. Dies liegt daran, dass die Nachrichten, aus denen sich ein Vorgang zusammensetzt, bei der Darstellung in verwaltetem Code entweder synchronen oder asynchronen Methoden zugeordnet werden können. Wenn Sie einen Client erstellen möchten, mit dem Vorgänge asynchron aufgerufen werden, können Sie daher mit Svcutil.exe und der Option /async asynchronen Clientcode generieren. Weitere Informationen finden Sie unter Gewusst wie: Asynchrones Aufrufen von Dienstvorgängen.

Aufrufen von Diensten mithilfe der WCF-Clientkanäle.

WCF-Clienttypen erweitern ClientBase<TChannel>, die wiederum von der System.ServiceModel.IClientChannel-Schnittstelle abgeleitet wird, um das zugrunde liegende Kanalsystem verfügbar zu machen. Sie können Dienste aufrufen, indem Sie den Zieldienstvertrag mit der System.ServiceModel.ChannelFactory<TChannel>-Klasse verwenden. Ausführliche Informationen finden Sie unter WCF-Clientarchitektur.

Siehe auch