Schritt 7: Implementieren des synchronen Ausgangshandlers für den Echo-Adapter
Abgeschlossene Zeit: 30 Minuten
In diesem Schritt implementieren Sie die synchrone Ausgehende Funktion des Echo-Adapters. Gemäß dem WCF LOB Adapter SDK müssen Sie die Microsoft.ServiceModel.Channels.Common.IOutboundHandler
Schnittstelle implementieren, um die synchrone Ausgehende Funktion zu unterstützen. Für den Echoadapter generiert der Adapterentwicklungs-Assistent automatisch eine abgeleitete Klasse namens EchoAdapterOutboundHandler.
In den folgenden Abschnitten aktualisieren Sie die EchoAdapterOutboundHandler-Klasse, um ein besseres Verständnis der Implementierung zu Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
erhalten, wie die eingehende WCF-Anforderungsnachricht analysiert und ausgehende WCF-Antwortnachrichten generiert werden.
Voraussetzungen
Bevor Sie mit diesem Schritt beginnen, müssen Sie Schritt 6: Implementieren des Metadatenauflösungshandlers für den Echoadapter erfolgreich abgeschlossen haben. Eine grundlegende Vertrautheit mit Microsoft.ServiceModel.Channels.Common.IOutboundHandler
ist ebenfalls hilfreich.
Die IOutboundHandler-Schnittstelle
Microsoft.ServiceModel.Channels.Common.IOutboundHandler
ist wie folgt definiert:
public interface IOutboundHandler : IConnectionHandler, IDisposable
{
Message Execute(Message message, TimeSpan timeout);
}
Die Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
-Methode führt die eingehende WCF-Anforderungsnachricht durch Aufrufen der entsprechenden Methode auf dem Zielsystem aus und gibt dann eine ausgehende WCF-Antwortnachricht zurück. Die Definitionen der zugehörigen Parameter sind in der folgenden Tabelle aufgeführt:
Parameter | Definition |
---|---|
message | Eingehende WCF-Anforderungsnachricht. |
timeout | Zeitintervall, innerhalb dessen dieser Vorgang abgeschlossen werden soll. Der Vorgang sollte einen System.TimeoutException auslösen, wenn das angegebene Timeout überschritten wird, bevor der Vorgang abgeschlossen ist. |
Wenn Ihr Adapter einen unidirektionalen Sendevorgang ausführt (vom Adapter wird keine Antwortnachricht erwartet), sollte diese Methode NULL zurückgeben. Wenn Ihr Adapter einen bidirektionalen Vorgang mit Microsoft.ServiceModel.Channels.Common.OperationResult
gleich Microsoft.ServiceModel.Channels.Common.OperationResult.Empty%2A
ausführt, gibt diese Methode eine WCF-Antwortnachricht mit einem leeren Text zurück. Andernfalls sollte die WCF-Antwortnachricht mit einem Textkörper zurückgegeben werden, der die Werte im Microsoft.ServiceModel.Channels.Common.OperationResult
-Objekt enthält. Verwenden Microsoft.ServiceModel.Channels.Common.OperationMetadata.OutputMessageAction%2A
Sie zum Erstellen der Antwortaktionszeichenfolge .
Synchroner ausgehender Echoadapter
Abhängig von den Vorgängen Ihres Zielsystems gibt es viele Möglichkeiten, die Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
Methode zu implementieren. Für den Echoadapter gibt es drei ausgehende Vorgänge, und die zugewiesenen Knoten-IDs und Anzeigenamen sind:
string[] EchoStrings(Zeichenfolgendaten), Knoten-ID = Echo/EchoString, display name=EchoString
Greeting[] EchoGreetings(Greeting greeting), node ID=Echo/EchoGreetings, display name=EchoGreetings
CustomGreeting EchoCustomGreetingFromFile(Uri greetingInstancePath), nodeID=Echo/EchoCustomGreetingFromFile, display name=EchoGreetings
Um die eingehende WCF-Anforderungsnachricht ordnungsgemäß zu analysieren und die ausgehende WCF-Antwortnachricht zu generieren, müssen Sie mit den folgenden Elementen in der SOAP-Nachricht vertraut sein, die vom WCF LOB Adapter SDK verwendet wird:
Für die eingehende WCF-Anforderungsnachricht:
Die WCF-Eingabemeldungsaktion = Knoten-ID des Vorgangs
Text der eingehenden Nachricht = Das Startelement des Textkörpers ist <displayname-Parametername>><{data}</Parametername></Anzeigename>
Für die ausgehende WCF-Antwortnachricht:
Die WCF-Ausgabemeldungsaktion = Knoten-ID des Vorgangs + "/antwort"
Text der ausgehenden Nachricht = Das Startelement des Textkörpers ist <displayname + "Response">, gefolgt von <displayname + "Result"> und gefolgt vom <Datentyp>data</datatype></displayname+"Result></displayname + "Response">
Beispiel: Vorgangszeichenfolge[] EchoStrings(Zeichenfolgendaten),Knoten-ID = Echo/EchoStrings und Anzeigename= EchoStrings:
Die WCF-Eingabemeldungsaktion = "Echo/EchoStrings"; und der Eingabetext sieht wie folgt aus, da der Parametername lautet
data
.
<EchoStrings>
<data>{data}
</data>
</EchoStrings>
Die WCF-Ausgabemeldungsaktion = "Echo/EchoStrings/Antwort"; und der Ausgabetext sieht wie folgt aus, da der Datentyp Zeichenfolge ist.
<EchoStringsResponse>
<EchoStringsResult>
<string>{data}</string>
</EchoStringsResult>
</EchoStringsResponse>
Wenn Sie die eingehende WCF-Anforderungsnachricht analysieren, können Sie den System.Xml.XmlDictionaryReader
verwenden, um Inhalte innerhalb der WCF-Nachricht abzurufen. Beim Verfassen der WCF-Antwortnachricht können Sie dazu den System.Xml.XmlWriter
verwenden.
Implementieren des IOutboundHandler
Sie implementieren die Execute-Methode von Microsoft.ServiceModel.Channels.Common.IOutboundHandler
. Ruft zunächst ein Microsoft.ServiceModel.Channels.Common.OperationMetadata
-Objekt basierend auf der Eingabemeldungsaktion ab. Analysiert dann die eingehende WCF-Nachricht und führt die zugeordnete Echofunktionalität basierend auf den einzelnen Vorgängen aus. Erstellt schließlich eine ausgehende WCF-Antwortnachricht im Format des ausgehenden Nachrichtentexts.
So implementieren Sie die Execute-Methode der EchoAdapterOutboundHandler-Klasse
Doppelklicken Sie in Projektmappen-Explorer auf die Datei EchoAdapterOutboundHandler.cs.
Fügen Sie im Visual Studio-Editor die folgenden beiden using-Anweisungen dem vorhandenen Satz von using-Anweisungen hinzu.
using System.Xml; using System.IO;
Ersetzen Sie in der Execute-Methode die vorhandene Logik durch Folgendes:
Diese Logik überprüft den angeforderten Vorgang.
Das Objekt wird basierend auf der
Microsoft.ServiceModel.Channels.Common.OperationMetadata
SOAP-Eingabemeldungsaktion abgerufen.Basierend auf dem Aktionstyp analysiert er die WCF-Anforderungsnachricht und ruft den entsprechenden Vorgang auf.
// Trace input message EchoAdapterUtilities.Trace.Trace(System.Diagnostics.TraceEventType.Verbose, "http://Microsoft.Adapters.Samples.Sql/TraceCode/InputWcfMessage", "Input WCF Message", this, new MessageTraceRecord(message)); // Timeout is not supported in this sample OperationMetadata om = this.MetadataLookup.GetOperationDefinitionFromInputMessageAction(message.Headers.Action, timeout); if (om == null) { throw new AdapterException("Invalid operation metadata for " + message.Headers.Action); } if (timeout.Equals(TimeSpan.Zero)) { throw new AdapterException("time out is zero"); } switch (message.Headers.Action) { case "Echo/EchoStrings": return ExecuteEchoStrings(om as ParameterizedOperationMetadata, message, timeout); case "Echo/EchoGreetings": return ExecuteEchoGreetings(om as ParameterizedOperationMetadata, message, timeout); case "Echo/EchoCustomGreetingFromFile": return ExecuteEchoCustomGreetingFromFile(om, message, timeout); } return null;
Fügen Sie nun die ExecuteEchoStrings-Methode hinzu, um den Vorgang string[] EchoStrings(string data) zu verarbeiten. Diese Hilfsfunktion liest die WCF-Anforderungsnachricht und überprüft, ob das echoInUpperCase-URI-Element auf true festgelegt ist. wenn dies der Fall ist, konvertiert sie die Eingabezeichenfolge so oft in Großbuchstaben, wie die Count-Variable angibt. Anschließend wird die WCF-Antwortnachricht im Format generiert: EchoStringsResponse><EchoStringResult><string>{data}</string></EchoStringResult></EchoStringsResponse>. <
private Message ExecuteEchoStrings(ParameterizedOperationMetadata om, Message message, TimeSpan timeout) { // ** Read the WCF request // ** <EchoStrings><name>{text}</name></EchoStrings> XmlDictionaryReader inputReader = message.GetReaderAtBodyContents(); while (inputReader.Read()) { if ((String.IsNullOrEmpty(inputReader.Prefix) && inputReader.Name.Equals("data")) || inputReader.Name.Equals(inputReader.Prefix + ":" + "data")) break; } inputReader.Read(); // if the connection property "echoInUpperCase" is set to true, it echoes the data in upper case bool echoInUpperCase = this.Connection.ConnectionFactory.ConnectionUri.EchoInUpperCase; string inputValue = echoInUpperCase ? inputReader.Value.ToUpper() : inputReader.Value; int arrayCount = this.Connection.ConnectionFactory.Adapter.Count; // ** Generate the WCF response // ** <EchoStringsResponse><EchoStringResult>{Name}</EchoStringResult></EchoStringsResponse > StringBuilder outputString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlWriter replywriter = XmlWriter.Create(outputString, settings); replywriter.WriteStartElement(om.DisplayName + "Response", EchoAdapter.SERVICENAMESPACE); replywriter.WriteStartElement(om.DisplayName + "Result", EchoAdapter.SERVICENAMESPACE); if (om.OperationResult.IsArray) { for (int count = 0; count < arrayCount; count++) { replywriter.WriteElementString("string", "http://schemas.microsoft.com/2003/10/Serialization/Arrays", inputValue); } } replywriter.WriteEndElement(); replywriter.WriteEndElement(); replywriter.Close(); XmlReader replyReader = XmlReader.Create(new StringReader(outputString.ToString())); return Message.CreateMessage(message.Version, om.OutputMessageAction, replyReader); }
Fahren Sie fort, indem Sie die ExecuteEchoGreetings-Methode hinzufügen, um den EchoGreetings-Vorgang zu behandeln. Diese Hilfsfunktion liest die WCF-Anforderungsnachricht, löst Vorgang und Typ nach den
ResolveOperationMetadata
Methoden undResolveTypeMetadata
derMicrosoft.ServiceModel.Channels.Common.IMetadataResolverHandler
Schnittstelle auf und generiert dann die WCF-Antwortnachricht im Format von EchoGreetingsResponse <><EchoGreetingsResult>... Nachricht...</EchoGreetingsResult></EchoGreetingsResponse>.private Message ExecuteEchoGreetings(ParameterizedOperationMetadata om, Message message, TimeSpan timeout) { // NOTE this method doesn't return response in upper case based on // connection property echoInUpperCase // ** Read the WCF request String inputValue = String.Empty; using (XmlDictionaryReader inputReader = message.GetReaderAtBodyContents()) { bool foundGreeting = inputReader.ReadToDescendant("greeting"); if (foundGreeting) { inputValue = inputReader.ReadInnerXml(); } } int arrayCount = this.Connection.ConnectionFactory.Adapter.Count; // ** Generate the WCF response StringBuilder outputString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlWriter replywriter = XmlWriter.Create(outputString, settings); replywriter.WriteStartElement(om.DisplayName + "Response", EchoAdapter.SERVICENAMESPACE); replywriter.WriteStartElement(om.DisplayName + "Result", EchoAdapter.SERVICENAMESPACE); for(int i = 0; i < arrayCount; i++ ) { ComplexQualifiedType cqtResult = om.OperationResult.QualifiedType as ComplexQualifiedType; StructuredTypeMetadata tmResult = MetadataLookup.GetTypeDefinition(cqtResult.TypeId, timeout) as StructuredTypeMetadata; replywriter.WriteStartElement(tmResult.TypeName, tmResult.TypeNamespace); replywriter.WriteRaw(inputValue); replywriter.WriteEndElement(); } replywriter.WriteEndElement(); replywriter.WriteEndElement(); replywriter.Close(); XmlReader replyReader = XmlReader.Create(new StringReader(outputString.ToString())); return Message.CreateMessage(message.Version, om.OutputMessageAction, replyReader); }
Fügen Sie nun die ExecuteEchoCustomGreetingFromFile-Methode hinzu, um den EchoCustomGreetingFromFile-Vorgang zu behandeln. Diese Hilfsfunktion liest die WCF-Anforderungsnachricht, liest die Nachricht aus der angegebenen Datei und generiert dann die WCF-Antwortnachricht im Format von EchoGreetingsFromFileResponse <><EchoGreetingsFromFileResult>... Nachricht...</EchoGreetingsFromFileResult></EchoGreetingsFromFileResponse>.
private Message ExecuteEchoCustomGreetingFromFile(OperationMetadata om, Message message, TimeSpan timeout) { // NOTE this method doesn't return response in upper case based on // connection property echoInUpperCase // ** Read the WCF request Uri path; using (XmlDictionaryReader inputReader = message.GetReaderAtBodyContents()) { inputReader.MoveToContent(); inputReader.ReadStartElement(om.DisplayName); inputReader.MoveToContent(); // The path contains the location of the XML file that contains the instance of Greeting object to read path = new Uri(inputReader.ReadElementContentAsString()); inputReader.ReadEndElement(); } // ** Generate the WCF response StringBuilder outputString = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlWriter replywriter = XmlWriter.Create(outputString, settings); replywriter.WriteStartElement(om.DisplayName + "Response", EchoAdapter.SERVICENAMESPACE); replywriter.WriteStartElement(om.DisplayName + "Result", EchoAdapter.SERVICENAMESPACE); // Read the XML file and set it to the reply writer here FileStream stream = new FileStream(path.AbsolutePath, FileMode.Open); XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); xdr.MoveToContent(); string rawGreeting = xdr.ReadInnerXml(); replywriter.WriteRaw(rawGreeting); replywriter.WriteEndElement(); replywriter.WriteEndElement(); replywriter.Close(); XmlReader replyReader = XmlReader.Create(new StringReader(outputString.ToString())); return Message.CreateMessage(message.Version, om.OutputMessageAction, replyReader); }
Klicken Sie in Visual Studio im Menü Datei auf Alle speichern.
Klicken Sie im Menü Erstellen auf Projektmappe erstellen. Es sollte ohne Fehler kompiliert werden. Wenn nicht, stellen Sie sicher, dass Sie alle oben genannten Schritte ausgeführt haben. Jetzt können Sie Visual Studio sicher schließen oder mit Schritt 8: Implementieren des synchronen eingehenden Handlers für den Echoadapter fortfahren.
Was habe ich nur getan?
In diesem Schritt haben Sie gelernt, wie Sie die synchrone Funktionalität für ausgehendes Messaging des Echo-Adapters implementieren. Dazu haben Sie die Microsoft.ServiceModel.Channels.Common.IOutboundHandler.Execute%2A
-Methode von Microsoft.ServiceModel.Channels.Common.IOutboundHandler
implementiert. Diese Methode analysierte die eingehende WCF-Anforderungsnachricht, führte die erforderlichen Aktionen aus und generierte dann die ausgehende WCF-Antwortnachricht.
Insbesondere für die eingehende WCF-Anforderungsnachricht haben Sie WCF System.ServiceModel.Channels.Message.Headers.Action%2A
verwendet, um die Eingabemeldungsaktion abzurufen, indem Sie sich mit der grundlegenden Struktur des Nachrichtentexts vertraut machen. Für die ausgehende WCF-Antwortnachricht haben Sie verwendet Microsoft.ServiceModel.Channels.Common.OperationMetadata.OutputMessageAction%2A
, um die Ausgabemeldungsaktion abzurufen, indem Sie sich mit der grundlegenden Struktur des Ausgehenden Nachrichtentexts vertraut machen. Beim Analysieren und Verfassen von WCF-Nachrichten haben Sie die System.Xml.XmlDictionaryReader
eingehende WCF-Anforderungsnachricht gelesen und System.Xml.XmlWriter
eine ausgehende WCF-Antwortnachricht geschrieben.
Nächste Schritte
Erstellen und Bereitstellen des Echo-Adapters
Weitere Informationen
Schritt 6: Implementieren des Handlers zum Löschen von Metadaten für den Echo-Adapter
Schritt 8: Implementieren des synchronen Eingangshandlers für den Echo-Adapter