Condividi tramite


Specifica del comportamento del client Run-Time

I client Windows Communication Foundation (WCF), come i servizi WCF (Windows Communication Foundation), possono essere configurati per modificare il comportamento di runtime in base all'applicazione client. Sono disponibili tre attributi per specificare il comportamento di runtime del client. Gli oggetti callback client duplex possono usare gli attributi CallbackBehaviorAttribute e CallbackDebugBehavior per modificare il loro comportamento di runtime. L'altro attributo , ClientViaBehavior, può essere usato per separare la destinazione logica dalla destinazione di rete immediata. Inoltre, i tipi di callback client duplex possono usare alcuni dei comportamenti del lato server. Per altre informazioni, vedere Specifica del comportamento Run-Time del servizio.

Uso dell'attributo CallbackBehaviorAttribute

È possibile configurare o estendere il comportamento di esecuzione di un'implementazione del contratto di callback in un'applicazione client usando la CallbackBehaviorAttribute classe . Questo attributo esegue una funzione simile per la classe di callback come la classe ServiceBehaviorAttribute, ad eccezione del comportamento di istanza e delle impostazioni delle transazioni.

La CallbackBehaviorAttribute classe deve essere applicata alla classe che implementa il contratto di callback. Se applicato a un'implementazione del contratto nonduplex, viene generata un'eccezione InvalidOperationException in fase di esecuzione. Nell'esempio di codice seguente viene illustrata una CallbackBehaviorAttribute classe in un oggetto callback che usa l'oggetto SynchronizationContext per determinare il thread a cui effettuare il marshalling, la proprietà per applicare la ValidateMustUnderstand convalida dei messaggi e la IncludeExceptionDetailInFaults proprietà per restituire eccezioni come FaultException oggetti al servizio a scopo di debug.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;

namespace Microsoft.WCF.Documentation
{
  [CallbackBehaviorAttribute(
   IncludeExceptionDetailInFaults= true,
    UseSynchronizationContext=true,
    ValidateMustUnderstand=true
  )]
  public class Client : SampleDuplexHelloCallback
  {
    AutoResetEvent waitHandle;

    public Client()
    {
      waitHandle = new AutoResetEvent(false);
    }

    public void Run()
    {
      // Picks up configuration from the configuration file.
      SampleDuplexHelloClient wcfClient
        = new SampleDuplexHelloClient(new InstanceContext(this), "WSDualHttpBinding_SampleDuplexHello");
      try
      {
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Enter a greeting to send and press ENTER: ");
        Console.Write(">>> ");
        Console.ForegroundColor = ConsoleColor.Green;
        string greeting = Console.ReadLine();
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Called service with: \r\n\t" + greeting);
        wcfClient.Hello(greeting);
        Console.WriteLine("Execution passes service call and moves to the WaitHandle.");
        this.waitHandle.WaitOne();
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("Set was called.");
        Console.Write("Press ");
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("ENTER");
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.Write(" to exit...");
        Console.ReadLine();
      }
      catch (TimeoutException timeProblem)
      {
        Console.WriteLine("The service operation timed out. " + timeProblem.Message);
        Console.ReadLine();
      }
      catch (CommunicationException commProblem)
      {
        Console.WriteLine("There was a communication problem. " + commProblem.Message);
        Console.ReadLine();
      }
    }
    public static void Main()
    {
      Client client = new Client();
      client.Run();
    }

    public void Reply(string response)
    {
      Console.WriteLine("Received output.");
      Console.WriteLine("\r\n\t" + response);
      this.waitHandle.Set();
    }
  }
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Threading

Namespace Microsoft.WCF.Documentation
    <CallbackBehaviorAttribute(IncludeExceptionDetailInFaults:=True, UseSynchronizationContext:=True, ValidateMustUnderstand:=True)> _
    Public Class Client
        Implements SampleDuplexHelloCallback
        Private waitHandle As AutoResetEvent

        Public Sub New()
            waitHandle = New AutoResetEvent(False)
        End Sub

        Public Sub Run()
            ' Picks up configuration from the configuration file.
            Dim wcfClient As New SampleDuplexHelloClient(New InstanceContext(Me), "WSDualHttpBinding_SampleDuplexHello")
            Try
                Console.ForegroundColor = ConsoleColor.White
                Console.WriteLine("Enter a greeting to send and press ENTER: ")
                Console.Write(">>> ")
                Console.ForegroundColor = ConsoleColor.Green
                Dim greeting As String = Console.ReadLine()
                Console.ForegroundColor = ConsoleColor.White
                Console.WriteLine("Called service with: " & Constants.vbCrLf & Constants.vbTab & greeting)
                wcfClient.Hello(greeting)
                Console.WriteLine("Execution passes service call and moves to the WaitHandle.")
                Me.waitHandle.WaitOne()
                Console.ForegroundColor = ConsoleColor.Blue
                Console.WriteLine("Set was called.")
                Console.Write("Press ")
                Console.ForegroundColor = ConsoleColor.Red
                Console.Write("ENTER")
                Console.ForegroundColor = ConsoleColor.Blue
                Console.Write(" to exit...")
                Console.ReadLine()
            Catch timeProblem As TimeoutException
                Console.WriteLine("The service operation timed out. " & timeProblem.Message)
                Console.ReadLine()
            Catch commProblem As CommunicationException
                Console.WriteLine("There was a communication problem. " & commProblem.Message)
                Console.ReadLine()
            End Try
        End Sub
        Public Shared Sub Main()
            Dim client As New Client()
            client.Run()
        End Sub

        Public Sub Reply(ByVal response As String) Implements SampleDuplexHelloCallback.Reply
            Console.WriteLine("Received output.")
            Console.WriteLine(Constants.vbCrLf & Constants.vbTab & response)
            Me.waitHandle.Set()
        End Sub
    End Class
End Namespace

Uso di CallbackDebugBehavior per abilitare il flusso di informazioni sulle eccezioni gestite

È possibile abilitare il flusso di informazioni sulle eccezioni gestite in un oggetto di callback client al servizio a scopo di debug impostando la proprietà IncludeExceptionDetailInFaults su true programmaticamente o da un file di configurazione dell'applicazione.

La restituzione di informazioni sulle eccezioni gestite ai servizi può essere un rischio per la sicurezza perché i dettagli delle eccezioni espongono informazioni sull'implementazione client interna che potrebbero essere usati da servizi non autorizzati. Inoltre, anche se le CallbackDebugBehavior proprietà possono essere impostate anche programmaticamente, può essere facile dimenticare di disabilitare IncludeExceptionDetailInFaults durante la distribuzione.

A causa dei problemi di sicurezza coinvolti, è consigliabile:

  • Usare un file di configurazione dell'applicazione per impostare il valore della IncludeExceptionDetailInFaults proprietà su true.

  • Questa operazione viene eseguita solo negli scenari di debug controllati.

Nell'esempio di codice seguente viene illustrato un file di configurazione client che indica a WCF di restituire informazioni sulle eccezioni gestite da un oggetto callback client nei messaggi SOAP.

  <client>
      <endpoint 
        address="http://localhost:8080/DuplexHello" 
        binding="wsDualHttpBinding"
        bindingConfiguration="WSDualHttpBinding_SampleDuplexHello"
        contract="SampleDuplexHello" 
        name="WSDualHttpBinding_SampleDuplexHello"
        behaviorConfiguration="enableCallbackDebug">
      </endpoint>
  </client>
<behaviors>
  <endpointBehaviors>
    <behavior name="enableCallbackDebug">
      <callbackDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

Uso del comportamento di ClientViaBehavior

È possibile utilizzare il ClientViaBehavior comportamento per specificare l'identificatore di risorsa uniforme per il quale deve essere creato il canale di trasporto. Utilizzare questo comportamento quando la destinazione di rete immediata non è il processore previsto del messaggio. Ciò consente conversazioni con più hop quando l'applicazione chiamante non conosce necessariamente la destinazione finale o quando l'intestazione di destinazione Via non è un indirizzo.

Vedere anche