Benutzerdefinierter NachrichteninterceptorCustom Message Interceptor

In diesem Beispiel wird die Verwendung des Kanalerweiterbarkeitsmodells veranschaulicht.This sample demonstrates the use of the channel extensibility model. Es zeigt insbesondere, wie ein benutzerdefiniertes Bindungselement implementiert wird, das Kanalfactorys und Kanallistener erstellt, um sämtliche ein- und ausgehenden Nachrichten an einer bestimmten Stelle im Laufzeitstapel abzufangen.In particular, it shows how to implement a custom binding element that creates channel factories and channel listeners to intercept all incoming and outgoing messages at a particular point in the run-time stack. Im Beispiel sind auch ein Client und ein Server, die die Verwendung dieser benutzerdefinierten Factorys veranschaulichen, enthalten.The sample also includes a client and server that demonstrate the use of these custom factories.

In diesem Beispiel sind sowohl der Client als auch der Dienst Konsolenprogramme (.exe).In this sample, both the client and the service are console programs (.exe). Der Client und der Dienst verwenden beide eine allgemeine Bibliothek (.dll), die das benutzerdefinierte Bindungselement und zugewiesene Laufzeitobjekte enthält.The client and service both make use of a common library (.dll) that contains the custom binding element and its associated run-time objects.

Hinweis

Die Setupprozedur und die Buildanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.The setup procedure and build instructions for this sample are located at the end of this topic.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\Channels\MessageInterceptor

Im Beispiel wird die empfohlene Vorgehensweise zum Erstellen eines benutzerdefinierten geschichteten Kanals in Windows Communication Foundation (WCF) anhand des kanalframeworks und WCF-best Practices beschrieben.The sample describes the recommended procedure for creating a custom layered channel in Windows Communication Foundation (WCF), by using the channel framework and following WCF best practices. Mit folgenden Schritten wird ein benutzerdefinierter geschichteter Kanal erstellt:The steps to create a custom layered channel are as follows:

  1. Legen Sie fest, welche Kanalform die Kanalfactory und der Kanallistener unterstützen sollen.Decide which of the channel shapes your channel factory and channel listener will support.

  2. Erstellen Sie eine Kanalfactory und einen Kanallistener, die Ihre Kanalformen unterstützen.Create a channel factory and a channel listener that support your channel shapes.

  3. Fügen Sie ein Bindungselement hinzu, das den benutzerdefinierten geschichteten Kanal einem Kanalstapel hinzufügt.Add a binding element that adds the custom layered channel to a channel stack.

  4. Fügen Sie einen Bindungselementerweiterungs-Abschnitt hinzu, um das neue Bindungselement für das Konfigurationssystem verfügbar zu machen.Add a binding element extension section to expose the new binding element to the configuration system.

KanalformenChannel Shapes

Der erste Schritt beim Schreiben eines benutzerdefinierten geschichteten Kanals besteht darin zu entscheiden, welche Formen für den Kanal erforderlich sind.The first step in writing a custom layered channel is to decide which shapes are required for the channel. Bei unserem Nachrichteninspektor wird jede Form unterstützt, die die Schicht unterhalb unterstützt (wenn die Schicht unterhalb beispielsweise IOutputChannel und IDuplexSessionChannel erstellen kann, werden ebenfalls IOutputChannel und IDuplexSessionChannel verfügbar gemacht).For our message inspector, we support any shape that the layer below us supports (for example, if the layer below us can build IOutputChannel and IDuplexSessionChannel, then we also expose IOutputChannel and IDuplexSessionChannel).

Kanalfactory und ListenerfactoryChannel Factory and Listener Factory

Der nächste Schritt beim Schreiben eines benutzerdefinierten geschichteten Kanals besteht im Erstellen einer Implementierung von IChannelFactory für Clientkanäle und von IChannelListener für Dienstkanäle.The next step in writing a custom layered channel is to create an implementation of IChannelFactory for client channels and of IChannelListener for service channels.

Diese Klassen nehmen eine innere Factory und einen inneren Listener und delegieren alle Aufrufe außer den OnCreateChannel- und OnAcceptChannel-Aufrufen an die innere Factory und den inneren Listener.These classes take an inner factory and listener, and delegate all but the OnCreateChannel and OnAcceptChannel calls to the inner factory and listener.

class InterceptingChannelFactory<TChannel> : ChannelFactoryBase<TChannel>  
{ ... }  
class InterceptingChannelListener<TChannel> : ListenerFactoryBase<TChannel>  
{ ... }  

Hinzufügen eines BindungselementsAdding a Binding Element

Das Beispiel definiert ein benutzerdefiniertes Bindungselement: InterceptingBindingElement.The sample defines a custom binding element: InterceptingBindingElement. InterceptingBindingElement akzeptiert eine ChannelMessageInterceptor als Eingabe und verwendet diesen ChannelMessageInterceptor zum Bearbeiten von Nachrichten, die sie durchlaufen.InterceptingBindingElement takes a ChannelMessageInterceptor as an input, and uses this ChannelMessageInterceptor to manipulate messages that pass through it. Dies ist die einzige Klasse, die öffentlich sein muss.This is the only class that must be public. Die Factory, der Listener und die Kanäle können alle interne Implementierungen der öffentlichen Laufzeitschnittstellen sein.The factory, listener, and channels can all be internal implementations of the public run-time interfaces.

public class InterceptingBindingElement : BindingElement  

Hinzufügen von KonfigurationsunterstützungAdding Configuration Support

Die Bibliothek definiert einen Konfigurationsabschnittshandler als Bindungselementerweiterungs-Abschnitt, um die Bindungskonfiguration zu integrieren.To integrate with binding configuration, the library defines a configuration section handler as a binding element extension section. Die Client- und Serverkonfigurationsdateien müssen die Bindungselementerweiterung auf dem Konfigurationssystem registrieren.The client and server configuration files must register the binding element extension with the configuration system. Implementierer, die ihr Bindungselement auf dem Konfigurationssystem verfügbar machen möchten, können von dieser Klasse ableiten.Implementers that want to expose their binding element to the configuration system can derive from this class.

public abstract class InterceptingElement : BindingElementExtensionElement { ... }  

Hinzufügen einer RichtlinieAdding Policy

Zum Integrieren mit unserem Richtliniensystem implementiert InterceptingBindingElement IPolicyExportExtension, um die Teilnahme beim Generieren der Richtlinie zu signalisieren.To integrate with our policy system, InterceptingBindingElement implements IPolicyExportExtension to signal that we should participate in generating policy. Damit das Importieren einer Richtlinie auf einem generierten Client unterstützt wird, kann der Benutzer eine abgeleitete Klasse von InterceptingBindingElementImporter registrieren und CreateMessageInterceptor() überschreiben, um die richtlinienfähige ChannelMessageInterceptor-Klasse zu generieren.To support importing policy on a generated client, the user can register a derived class of InterceptingBindingElementImporter and override CreateMessageInterceptor() to generate their policy-enabled ChannelMessageInterceptor class.

Beispiel: Zu verwerfender NachrichteninspektorExample: Droppable Message Inspector

Das Beispiel umfasst eine Beispielimplementierung von ChannelMessageInspector, der Meldungen verwirft.Included in the sample is an example implementation of ChannelMessageInspector which drops messages.

class DroppingServerElement : InterceptingElement  
{  
    protected override ChannelMessageInterceptor CreateMessageInterceptor()  
    {  
        return new DroppingServerInterceptor();  
    }  
}  

Sie rufen es wie folgt über die Konfiguration auf:You can access it from configuration as follows:

<configuration>  
    ...  
    <system.serviceModel>  
        ...  
        <extensions>  
            <bindingElementExtensions>  
                <add name="droppingInterceptor"   
                   type=  
          "Microsoft.ServiceModel.Samples.DroppingServerElement, library"/>  
            </bindingElementExtensions>  
        </extensions>  
    </system.serviceModel>  
</configuration>  

Sowohl der Client als auch der Server verwenden den neu erstellten Konfigurationsabschnitt, um die benutzerdefinierten Factorys in die unterste Schicht ihrer Laufzeit-Kanalstapel (über der Transportebene) einzufügen.The client and server both use this newly created configuration section to insert the custom factories into the lowest-level of their run-time channel stacks (above the transport level).

<customBinding>  
  <binding name="sampleBinding">  
    <droppingInterceptor/>  
    <httpTransport/>  
  </binding>  
</customBinding>  

Der Client verwendet die MessageInterceptor-Bibliothek, um einen benutzerdefinierten Header für Meldungen mit geraden Zahlen hinzuzufügen.The client uses the MessageInterceptor library to add a custom header to even numbered messages. Der Dienst hingegen verwendet die MessageInterceptor-Bibliothek, um alle Meldungen zu verwerfen, die diesen Header nicht enthalten.The service on the other hand uses MessageInterceptor library to drop any messages that do not have this special header.

Nach Ausführen des Diensts und anschließendem Ausführen des Clients sollte folgende Clientausgabe angezeigt werden:You should see the following client output after running the service and then the client.

Reporting the next 10 wind speed  
100 kph  
Server dropped a message.  
90 kph  
80 kph  
Server dropped a message.  
70 kph  
60 kph  
Server dropped a message.  
50 kph  
40 kph  
Server dropped a message.  
30 kph  
20 kph  
Server dropped a message.  
10 kph  
Press ENTER to shut down client  

Der Client meldet 10 verschiedene Windgeschwindigkeiten an den Dienst, aber nur die Hälfte der Meldungen wird mit dem speziellen Header gekennzeichnet.The client reports 10 different wind speeds to the service, but only tags half of them with the special header.

Auf dem Dienst sollten Sie die folgende Ausgabe erhalten:On the service, you should see the following output:

Press ENTER to exit.  
Dangerous wind detected! Reported speed (90) is greater than 64 kph.  
Dangerous wind detected! Reported speed (70) is greater than 64 kph.  
5 wind speed reports have been received.  

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Installieren Sie ASP.NETASP.NET 4.0 mithilfe des folgenden Befehls.Install ASP.NETASP.NET 4.0 using the following command.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable  
    
  2. Stellen Sie sicher, dass Sie ausgeführt haben die Setupprozedur für die Windows Communication Foundation-Beispiele zum einmaligen.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  3. Führen Sie zum Erstellen der Projektmappe die Anweisungen im Erstellen der Windows Communication Foundation-Beispiele.To build the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  4. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

  5. Führen Sie zuerst "Service.exe" und dann "Client.exe" aus, und sehen Sie sich die Ausgabe in beiden Konsolenfenstern an.Run Service.exe first then run Client.exe and watch both console windows for output.

Siehe auchSee Also