Streamen Flat-File IDOCs in SAP mithilfe des WCF-Kanalmodells
Der Microsoft BizTalk-Adapter für mySAP Business Suite unterstützt das Node-Wert-Streaming für die Vorgänge SendIdoc und ReceiveIdoc. Diese Vorgänge werden zum Senden und Empfangen von Flatfile-IDOCs (Zeichenfolgen) an und vom Adapter verwendet. In beiden Vorgängen sind die Daten für das gesamte IDOC in einer Zeichenfolge unter einem einzelnen Knoten (<idocData>) enthalten. Bei großen IDOCs kann das Streamen der IDOC-Daten zwischen dem Adapter und Ihrem Code erhebliche Speicherressourcen sparen.
Hintergrundinformationen dazu, wie der Adapter Streaming unterstützt, finden Sie unter Streaming und SAP-Adapter. Sie sollten dieses Thema lesen, bevor Sie fortfahren.
In den Abschnitten in diesem Thema wird beschrieben, wie Sie das Knoten-Wert-Streaming für die SendIdoc- und ReceiveIdoc-Vorgänge implementieren, wenn Sie das WCF-Kanalmodell verwenden.
Streaming ausgehender Flat-File IDOCs an den Adapter
Der Adapter unterstützt das Knotenwertstreaming für die Anforderungsnachricht für den SendIdoc-Vorgang.
Um das Knotenwertstreaming für SendIdoc-Vorgänge im WCF-Kanalmodell zu unterstützen, müssen Sie:
Implementieren Sie ein System.ServiceModel.Channels.BodyWriter , das in der Lage ist, die IDOC-Daten zu streamen (Knotenwert-Streaming für die IDOC-Daten).
Erstellen Sie system.ServiceModel.Message , die zum Aufrufen des Vorgangs verwendet wird, indem Sie den Nachrichtentext mit diesem BodyWriter mithilfe einer entsprechenden Überladung der Message.Create-Methode bereitstellen.
Implementieren eines BodyWriter
Das folgende Beispiel zeigt eine Implementierung eines BodyWriter-Steuerelements , das Das Streaming mit Knotenwert ausführt.
/// <summary>
/// This class overrides the OnWriteBodyContents function to do node-value streaming
/// </summary>
class StreamingBodyWriter : BodyWriter, IDisposable
{
XmlReader m_reader = null;
int m_chunkSize;
/// <summary>
/// Initializes the body writer
/// </summary>
/// <param name="reader">Reader for input</param>
/// <param name="chunkSize">The chunksize in which the data is passed to adapter</param>
public StreamingBodyWriter(XmlReader reader, int chunkSize)
: base(false)
{
m_reader = reader;
if (chunkSize <= 0)
throw new ApplicationException("ChunkSize should be a positive value");
m_chunkSize = chunkSize;
}
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
if (m_reader == null)
throw new ApplicationException("Reader cannot be null");
while (m_reader.Read())
{
switch (m_reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(m_reader.LocalName, m_reader.NamespaceURI);
break;
case XmlNodeType.Text:
#region Streaming Code
char[] tempBuffer = new char[m_chunkSize];
int length = 0;
while ((length = m_reader.ReadValueChunk(tempBuffer, 0, m_chunkSize)) > 0)
{
writer.WriteString(new String(tempBuffer, 0, length));
}
#endregion
break;
case XmlNodeType.EndElement:
writer.WriteEndElement();
break;
}
}
}
#region IDisposable Members
public void Dispose()
{
if (m_reader != null)
{
m_reader.Close();
m_reader = null;
}
}
#endregion
}
Erstellen einer Nachricht mit einem BodyWriter
Das folgende Beispiel zeigt, wie Sie eine SendIdoc-Anforderungsnachricht mithilfe des BodyWriter im vorherigen Beispiel erstellen. Die Nachrichtendaten werden aus einer Datei gelesen.
XmlReader readerIn = XmlReader.Create ("sendidoc.xml");
// StreamingBodyWrtier class is responsible for streaming
StreamingBodyWriter stBW = new StreamingBodyWriter(readerIn, chunkSize);
Message InputMsg = Message.CreateMessage(MessageVersion.Default,
"http://Microsoft.LobServices.SAP/2007/03/Idoc/SendIdoc",
stBW);
Streaming eingehender Flat-File IDOCs vom Adapter
Sie erhalten eine Flatfile-IDOCs im Eingehenden ReceiveIdoc-Vorgang. Der Adapter unterstützt das Knotenwertstreaming für die Anforderungsnachricht für den ReceiveIdoc-Vorgang.
Um das Node-Wert-Streaming für ReceiveIdoc-Vorgänge im WCF-Kanalmodell zu unterstützen, müssen Sie:
Implementieren sie eine System.Xml. XmlDictionaryWriter , das in der Lage ist, die IDOC-Daten zu streamen (knotenwertbasiertes Streaming für die IDOC-Daten).
Nutzen Sie die Nachricht , indem Sie die WriteBodyContents-Methode mit diesem XmlDictionaryWriter aufrufen.
Implementieren eines XmlDictionaryWriter
Das folgende Beispiel zeigt eine Implementierung eines XmlDictionaryWriter,das Knotenwertstreaming ausführt.
using System;
using System.Xml;
using System.Text;
class FileXmlWriter : XmlDictionaryWriter
{
XmlTextWriter xts;
public FileXmlWriter(string file)
{
xts = new XmlTextWriter(file, Encoding.UTF8);
}
public override void WriteBase64(byte[] buffer, int index, int count)
{
xts.WriteBase64(buffer, index, count);
}
public override void WriteCData(string text)
{
xts.WriteCData(text);
}
public override void WriteCharEntity(char ch)
{
xts.WriteCharEntity(ch);
}
public override void WriteChars(char[] buffer, int index, int count)
{
xts.WriteChars(buffer, index, count);
}
public override void WriteComment(string text)
{
xts.WriteComment(text);
}
public override void WriteDocType(string name, string pubid, string sysid, string subset)
{
xts.WriteDocType(name, pubid, sysid, subset);
}
public override void WriteEndAttribute()
{
xts.WriteEndAttribute();
}
public override void WriteEndDocument()
{
xts.WriteEndDocument();
}
public override void WriteEndElement()
{
xts.WriteEndElement();
}
public override void WriteEntityRef(string name)
{
xts.WriteEntityRef(name);
}
public override void WriteFullEndElement()
{
xts.WriteFullEndElement();
}
public override void WriteProcessingInstruction(string name, string text)
{
xts.WriteProcessingInstruction(name, text);
}
public override void WriteRaw(string data)
{
xts.WriteRaw(data);
}
public override void WriteRaw(char[] buffer, int index, int count)
{
xts.WriteRaw(buffer, index, count);
}
public override void WriteStartAttribute(string prefix, string localName, string ns)
{
xts.WriteStartAttribute(prefix, localName, ns);
}
public override void WriteStartDocument(bool standalone)
{
xts.WriteStartDocument(standalone);
}
public override void WriteStartDocument()
{
xts.WriteStartDocument();
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
xts.WriteStartElement(localName);
}
public override void WriteString(string text)
{
xts.WriteString(text);
}
public override void WriteSurrogateCharEntity(char lowChar, char highChar)
{
xts.WriteSurrogateCharEntity(lowChar, highChar);
}
public override void WriteWhitespace(string ws)
{
xts.WriteWhitespace(ws);
}
public override void Close()
{
xts.Close();
}
public override void Flush()
{
xts.Flush();
}
public override string LookupPrefix(string ns)
{
return xts.LookupPrefix(ns);
}
public override WriteState WriteState
{
get { return xts.WriteState; }
}
}
Verwenden einer Nachricht mithilfe eines XmlDictionaryWriter
Das folgende Beispiel zeigt, wie Sie eine ReceiveIdoc-Anforderungsnachricht mithilfe des im vorherigen Beispiel implementierten FileXmlWriter nutzen. (Die FileWriter-Klasse wurde durch Die Unterklassierung von XmlDictionaryWriter erstellt.) Im Beispiel wird ein IReplyChannel-Kanal verwendet, um den ReceiveIdoc-Vorgang zu empfangen. Die Details der Kanalerstellung wurden nicht angegeben. Die ReceiveIdoc-Anforderungsnachricht wird in eine Datei geschrieben.
// Receive the ReceiveIdoc request message from the adapter.
RequestContext rc = channel.ReceiveRequest();
Message inputMsg = rc.RequestMessage;
// Stream the request message to received_idoc.xml using the custom XmlDictionaryWriter.
FileXmlWriter fileXmlWriter = new FileXmlWriter("received_idoc.xml");
inputMsg.WriteBodyContents(fileXmlWriter);
fileXmlWriter.Flush();
fileXmlWriter.Close();