Vorgangsformatierer und VorgangsauswahlOperation Formatter and Operation Selector

In diesem Beispiel wird veranschaulicht, wie Erweiterungspunkte für Windows Communication Foundation (WCF) verwendet werden können, um Nachrichtendaten in einem anderen Format von Was WCF erwartet zuzulassen.This sample demonstrates how Windows Communication Foundation (WCF) extensibility points can be used to allow message data in a different format from what WCF expects. Standardmäßig erwarten WCF Formatierungsprogramme Methodenparameter unter einzuschließenden der soap:body Element.By default, WCF formatters expect method parameters to be included under the soap:body element. Das Beispiel zeigt, wie ein benutzerdefinierter Vorgangsformatierer implementiert wird, der Parameterdaten aus einer HTTP-GET-Abfragezeichenfolge stattdessen analysiert und mit diesen Daten dann Methoden aufruft.The sample shows how to implement a custom operation formatter that parses parameter data from an HTTP GET query string instead and invokes methods using that data.

Das Beispiel basiert auf der Einstieg, implementiert die ICalculator Dienstvertrag.The sample is based on the Getting Started, which implements the ICalculator service contract. Es zeigt, wie Add-, Subtract-, Multiply- und Divide-Nachrichten so geändert werden können, dass für Client-an-Server-Anforderungen HTTP GET und für Server-zu-Client-Antworten HTTP POST mit POX-Nachrichten verwendet werden.It shows how Add, Subtract, Multiply, and Divide messages can be changed to use HTTP GET for client-to-server requests and HTTP POST with POX messages for server-to-client responses.

Zu diesem Zweck enthält das Beispiel Folgendes:To do so, the sample provides the following:

  • QueryStringFormatter, der IClientMessageFormatter und IDispatchMessageFormatter für den Client bzw. den Server implementiert und die Daten in der Abfragezeichenfolge verarbeitet.QueryStringFormatter, which implements IClientMessageFormatter and IDispatchMessageFormatter for the client and server, respectively, and processes the data in the query string.

  • UriOperationSelector, die IDispatchOperationSelector auf dem Server implementiert, um die Vorgangsverteilung anhand des Vorgangsnamens in der GET-Anforderung zu verteilen.UriOperationSelector, which implements IDispatchOperationSelector on the server to perform operation dispatch based on the operation name in the GET request.

  • EnableHttpGetRequestsBehavior-Endpunktverhalten (und entsprechende Konfiguration), das die erforderliche Vorgangsauswahl der Laufzeit hinzufügt.EnableHttpGetRequestsBehavior endpoint behavior (and corresponding configuration), which adds the necessary operation selector to the runtime.

  • Zeigt, wie ein neuer Vorgangsformatierer in die Laufzeit eingefügt wird.Shows how to insert a new operation formatter into the runtime.

  • In diesem Beispiel sind sowohl der Client als auch der Dienst Konsolenanwendungen (.exe).In this sample, both the client and the service are console applications (.exe).

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.

GrundbegriffeKey Concepts

QueryStringFormatter -Der vorgangsformatierer ist die Komponente in WCF, die für das Umwandeln einer Nachricht in ein Array von Parameterobjekten und ein Array von Parameterobjekten in eine Nachricht verantwortlich ist.QueryStringFormatter - The operation formatter is the component in WCF that is responsible for converting a message into an array of parameter objects and an array of parameter objects into a message. Auf dem Client erfolgt dies mithilfe der IClientMessageFormatter-Schnittstelle, und auf dem Server mit der IDispatchMessageFormatter-Schnittstelle.This is done on the client using the IClientMessageFormatter interface and on the server with the IDispatchMessageFormatter interface. Mit diesen Schnittstellen können Benutzer die Anforderungs- und Antwortnachrichten aus der Serialize-Methode und der Deserialize-Methode abrufen.These interfaces enable users to get the request and response messages from the Serialize and Deserialize methods.

In diesem Beispiel implementiert QueryStringFormatter beide Schnittstellen und wird sowohl auf dem Client als auch auf dem Server implementiert.In this sample, QueryStringFormatter implements both of these interfaces and is implemented on the client and server.

Anforderung:Request:

  • Das Beispiel verwendet die TypeConverter-Klasse, um Parameterdaten in der Anforderungsnachricht in und aus Zeichenfolgen zu konvertieren.The sample uses the TypeConverter class to convert parameter data in the request message to and from strings. Wenn ein TypeConverter für einen bestimmten Typ nicht verfügbar ist, löst der Beispielformatierer eine Ausnahme aus.If a TypeConverter is not available for a specific type, the sample formatter throws an exception.

  • In der IClientMessageFormatter.SerializeRequest-Methode auf dem Client erstellt der Formatierer einen URI mit der entsprechenden Empfängeradresse und fügt den Vorgangsnamen als Suffix an.In the IClientMessageFormatter.SerializeRequest method on the client, the formatter creates a URI with the appropriate To address and appends the operation name as a suffix. Dieser Name dient dann zum Verteilen zum entsprechenden Vorgang auf dem Server.This name is used to dispatch to the appropriate operation on the server. Dann nimmt er das Array mit Parameterobjekten und serialisiert die Parameterdaten mithilfe von Parameternamen und den von der TypeConverter-Klasse konvertierten Werten in die URI-Abfragezeichenfolge.It then takes the array of parameter objects and serializes the parameter data to the URI query string using parameter names and the values converted by the TypeConverter class. Die To-Eigenschaft und die Via-Eigenschaft werden dann auf diesen URI festgelegt.The To and Via properties are then set to this URI. Auf MessageProperties wird über die Properties-Eigenschaft zugegriffen.MessageProperties is accessed through the Properties property.

  • In der IDispatchMessageFormatter.DeserializeRequest-Methode auf dem Server ruft der Formatierer den Via-URI in den Eigenschaften der eingehenden Anforderungsnachricht ab.In the IDispatchMessageFormatter.DeserializeRequest method on the server, the formatter retrieves the Via URI in the incoming request message properties. Er analysiert die Name-Wert-Paare in der URI-Abfragezeichenfolge in Parameternamen und Werte und füllt mit diesen Parameternamen und Werten das an die Methode übergebene Parameterarray auf.It parses the name-value pairs in the URI query string into parameter names and values and uses the parameter names and values to populate the array of parameters passed into the method. Beachten Sie, dass die Vorgangsverteilung bereits stattgefunden hat; daher wird das Namenssuffix in dieser Methode ignoriert.Note that operation dispatch has already occurred, so the operation name suffix is ignored in this method.

Antwort:Response:

  • In diesem Beispiel wird HTTP GET nur für die Anforderung verwendet.In this sample, HTTP GET is used only for the request. Der Formatierer delegiert das Senden der Antwort an den ursprünglichen Formatierer, von dem XML-Nachrichten generiert worden wären.The formatter delegates the sending of the response to the original formatter that would have been used to generate an XML message. Eines der Ziele dieses Beispiels besteht darin, zu zeigen, wie solch ein delegierender Formatierer implementiert werden kann.One of the goals of this sample is to show how such a delegating formatter can be implemented.

UriPathSuffixOperationSelector-KlasseUriPathSuffixOperationSelector Class

Mit der IDispatchOperationSelector-Schnittstelle können Benutzer ihre eigene Logik für die Entscheidung implementieren, für welchen Vorgang eine bestimmte Nachricht weitergeleitet werden soll.The IDispatchOperationSelector interface enables users to implement their own logic for which operation a particular message should be dispatched.

In diesem Beispiel muss UriPathSuffixOperationSelector zum Auswählen des entsprechenden Vorgangs auf dem Server implementiert werden, da anstelle eines Aktionsheaders in der Nachricht der Vorgangsname in dem HTTP-GET-URI eingetragen wird.In this sample, UriPathSuffixOperationSelector must be implemented on the server to select the appropriate operation because the operation name is included in the HTTP GET URI rather than an action header in the message. Das Beispiel ist so eingerichtet, dass bei Vorgangsnamen die Groß- und Kleinschreibung nicht beachtet werden muss.The sample is set up to allow only case-insensitive operation names.

Die SelectOperation-Methode nimmt die eingehende Nachricht entgegen und schlägt den Via-URI in deren Nachrichteneigenschaften nach.The SelectOperation method takes the incoming message and looks up the Via URI in its message properties. Sie extrahiert das Vorgangsnamenssuffix aus dem URI, schlägt in einer internen Tabelle den Namen des Vorgangs nach, an den die Nachricht weitergeleitet werden soll, und gibt diesen Vorgangsnamen dann zurück.It extracts the operation name suffix from the URI, looks up an internal table to get the operation name that the message should be dispatched to, and returns that operation name.

EnableHttpGetRequestsBehavior-KlasseEnableHttpGetRequestsBehavior Class

Die UriPathSuffixOperationSelector-Komponente kann programmgesteuert oder über ein Endpunktverhalten eingerichtet werden.The UriPathSuffixOperationSelector component can be set up programmatically or through an endpoint behavior. Das Beispiel implementiert das EnableHttpGetRequestsBehavior-Verhalten, das in der Anwendungskonfigurationsdatei des Diensts angegeben wird.The sample implements the EnableHttpGetRequestsBehavior behavior, which is specified in service’s application configuration file.

Auf dem Server:On the server:

Der OperationSelector wird auf die IDispatchOperationSelector-Implementierung festgelegt.The OperationSelector is set to the IDispatchOperationSelector implementation.

WCF verwendet standardmäßig einen Adressfilter mit exakter Übereinstimmung.By default, WCF uses an exact-match address filter. Der URI in der eingehenden Nachricht enthält ein Vorgangsnamenssuffix, gefolgt von einer Abfragezeichenfolge, die Parameterdaten enthält. Daher ändert das Endpunktverhalten auch den Adressfilter in einen Präfixübereinstimmungsfilter.The URI on the incoming message contains an operation name suffix followed by a query string that contains parameter data, so the endpoint behavior also changes the address filter to be a prefix match filter. Er verwendet den WCFPrefixEndpointAddressMessageFilter für diesen Zweck.It uses the WCFPrefixEndpointAddressMessageFilter for this purpose.

Installieren von VorgangsformatierernInstalling operation formatters

Vorgangsverhaltensweisen, die Formatierer angeben, sind eindeutig.Operation behaviors that specify formatters are unique. Standardmäßig wird ein solches Verhalten für jeden Vorgang stets zum Erstellen des erforderlichen Vorgangsformatierers implementiert.One such behavior is always implemented by default for every operation to create the necessary operation formatter. Auch wenn diese Verhaltensweisen wie noch ein weiteres Vorgangsverhalten aussehen mögen, sind sie nicht durch andere Attribute zu identifizieren.However, these behaviors look like just another operation behavior; they are not identifiable by any other attribute. Zum Installieren eines ersatzverhaltens muss die Implementierung suchen Sie nach bestimmten Formatierers Verhaltensweisen, die von den WCF-typladeprogramm standardmäßig und entweder installiert werden, die sie ersetzen, oder fügen ein kompatibles Verhalten nach dem Standardverhalten ausgeführt.To install a replacement behavior, the implementation must look for specific formatter behaviors that are installed by the WCF type loader by default and either replace it or add a compatible behavior to run after the default behavior.

Diese Vorgangsformatiererverhalten können programmgesteuert vor dem Aufruf von CommunicationObject.Open eingerichtet werden, oder indem man ein Vorgangsverhalten angibt, das nach dem Standardverhalten ausgeführt wird.These operation formatters behaviors can be set up programmatically prior to calling CommunicationObject.Open or by specifying an operation behavior that is executed after the default one. Es kann jedoch nicht einfach wie ein Endpunktverhalten (und damit per Konfiguration) eingerichtet werden, da das Verhaltensmodell das Ersetzen eines Verhaltens durch ein anderes oder sonstiges Ändern der Beschreibungsstruktur nicht zulässt.However, it cannot easily be set up by an endpoint behavior (and therefore by configuration) because the behavior model does not allow a behavior to replace other behaviors or otherwise modify the description tree.

Auf dem Client:On the client:

Die IClientMessageFormatter-Implementierung muss implementiert werden, damit sie die Anforderungen in HTTP-GET-Anforderungen konvertieren und für Antworten an den ursprünglichen Formatierer delegieren kann.The IClientMessageFormatter implementation must be implemented so that it can convert the requests into HTTP GET requests and delegate to the original formatter for responses. Dies erfolgt durch Aufrufen der EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior-Hilfsmethode.This is done by calling the EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior helper method.

Es muss vor dem Aufruf von CreateChannel durchgeführt werden.This must be done before calling CreateChannel.

void ReplaceFormatterBehavior(OperationDescription operationDescription, EndpointAddress address)  
{  
    // Remove the DataContract behavior if it is present.  
    IOperationBehavior formatterBehavior = operationDescription.Behaviors.Remove<DataContractSerializerOperationBehavior>();  
    if (formatterBehavior == null)  
    {  
        // Remove the XmlSerializer behavior if it is present.  
        formatterBehavior = operationDescription.Behaviors.Remove<XmlSerializerOperationBehavior>();  
        ...  
    }  

    // Remember what the innerFormatterBehavior was.  
    DelegatingFormatterBehavior delegatingFormatterBehavior = new DelegatingFormatterBehavior(address);  
    delegatingFormatterBehavior.InnerFormatterBehavior = formatterBehavior;  
   operationDescription.Behaviors.Add(delegatingFormatterBehavior);  
}  

Auf dem Server:On the server:

  • Die IDispatchMessageFormatter-Schnittstelle muss implementiert werden, damit sie HTTP-GET-Anforderungen lesen und zum Schreiben von Antworten an den ursprünglichen Formatierer delegieren kann.The IDispatchMessageFormatter interface must be implemented so that it can read HTTP GET requests and delegate to the original formatter for writing responses. Dies erfolgt durch Aufrufen derselben EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior-Hilfsmethode wie beim Client (siehe vorheriges Codebeispiel).This is done by calling the same EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior helper method as the client (see the previous code sample).

  • Das muss erfolgen, bevor Open aufgerufen wird.This must be done before Open is called. In diesem Beispiel wird gezeigt, wie der Formatierer manuell geändert wird, bevor Open aufgerufen wird.In this sample, we show how the formatter is manually modified before calling Open. Dasselbe lässt sich auch erreichen, indem man eine Klasse von ServiceHost ableitet, die vor dem Öffnen EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior aufruft (Beispiel dazu finden Sie in der Hostingdokumentation).Another way to achieve the same thing is to derive a class from ServiceHost that makes the calls to EnableHttpGetRequestsBehavior.ReplaceFormatterBehavior before opening (please see hosting documentation and samples for examples).

BenutzerfreundlichkeitUser experience

Auf dem Server:On the server:

  • Die ICalculator-Serverimplementierung muss nicht geändert werden.The server ICalculator implementation does not need to change.

  • Die App.config-Datei für den Dienst muss eine benutzerdefinierte POX-Bindung verwenden, die für das messageVersion-Attribut des textMessageEncoding-Elements None festlegt.The App.config for the service must use a custom POX binding that sets the messageVersion attribute of the textMessageEncoding element to None.

    <bindings>  
      <customBinding>  
        <binding name="poxBinding">  
          <textMessageEncoding messageVersion="None" />  
          <httpTransport />  
        </binding>  
      </customBinding>  
    </bindings>  
    
  • Außerdem muss die App.config-Datei für den Dienst das benutzerdefinierte EnableHttpGetRequestsBehavior angeben, indem sie es dem Abschnitt mit den Verhaltenserweiterungen hinzufügt und verwendet.The App.config for the service also must specify the custom EnableHttpGetRequestsBehavior by adding it to the behavior extensions section and using it.

    <behaviors>  
      <endpointBehaviors>  
        <behavior name="enableHttpGetRequestsBehavior">  
          <enableHttpGetRequests />  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
    
    <extensions>  
      <behaviorExtensions>  
        <!-- Enabling HTTP GET requests: Behavior Extension -->  
        <add   
          name="enableHttpGetRequests"           type="Microsoft.ServiceModel.Samples.EnableHttpGetRequestsBehaviorElement, QueryStringFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />  
      </behaviorExtensions>  
    </extensions>  
    
  • Fügen Sie Vorgangsformatierer vor dem Aufrufen von Open hinzu.Add operation formatters before calling Open.

Auf dem Client:On the client:

  • Die Clientimplementierung muss nicht geändert werden.The client implementation does not need to change.

  • Die App.config-Datei für den Client muss eine benutzerdefinierte POX-Bindung verwenden, die für das messageVersion-Attribut des textMessageEncoding-Elements None festlegt.The App.config for the client must use a custom POX binding that sets the messageVersion attribute of the textMessageEncoding element to None. Ein Unterschied zum Dienst besteht darin, dass der Client die manuelle Adressierung aktivieren muss, damit die Empfängeradresse der ausgehenden Nachricht geändert werden kann.One difference from the service is that the client must enable manual addressing so that the outgoing To address can be modified.

    <bindings>  
      <customBinding>  
        <binding name="poxBinding">  
          <textMessageEncoding messageVersion="None" />  
          <httpTransport manualAddressing="True" />  
        </binding>  
      </customBinding>  
    </bindings>  
    
  • Die App.config für den Client muss dasselbe benutzerdefinierte EnableHttpGetRequestsBehavior wie der Server angeben.The App.config for the client must specify the same custom EnableHttpGetRequestsBehavior as the server.

  • Fügen Sie Vorgangsformatierer vor dem Aufrufen von CreateChannel() hinzu.Add operation formatters before calling CreateChannel().

Wenn Sie das Beispiel ausführen, werden die Anforderungen und Antworten für den Vorgang im Clientkonsolenfenster angezeigt.When you run the sample, the operation requests and responses are displayed in the client console window. Alle vier Vorgänge (Add, Subtract, Multiply und Divide) müssen erfolgreich sein.All four operations (Add, Subtract, Multiply, and Divide) must succeed.

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\Formatters\QuieryStringFormatter

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample
  1. 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.

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

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

Siehe auchSee Also