次の方法で共有


WCF チャネル モデルを使用して SAP Flat-File IDOC をストリーミングする

Microsoft BizTalk Adapter for mySAP Business Suite では、SendIdoc 操作と ReceiveIdoc 操作のノード値ストリーミングがサポートされています。 これらの操作は、アダプターとの間でフラット ファイル (文字列) IDOC を送受信するために使用されます。 どちらの操作でも、IDOC 全体のデータは、単一ノード (<idocData>) の下の文字列に含まれます。 大規模な IDOC の場合、アダプターとコードの間で IDOC データをストリーミングすると、大量のメモリ リソースが節約される可能性があります。

アダプターがストリーミングをサポートする方法の背景情報については、「 ストリーミングと SAP アダプター」を参照してください。 先に進む前に、このトピックをお読みください。

このトピックのセクションでは、WCF チャネル モデルを使用するときに SendIdoc および ReceiveIdoc 操作のノード値ストリーミングを実装する方法について説明します。

アダプターへのアウトバウンド Flat-File IDOC のストリーミング

アダプターは、SendIdoc 操作の要求メッセージでノード値ストリーミングをサポートします。

WCF チャネル モデルの SendIdoc 操作でノード値ストリーミングをサポートするには、次の操作を行う必要があります。

  1. IDOC データをストリーミングできる System.ServiceModel.Channels.BodyWriter を実装します (IDOC データに対してノード値ストリーミングを実行します)。

  2. Message.Create メソッドの適切なオーバーロードを使用して、この BodyWriter でメッセージ本文を指定して、操作の呼び出しに使用する System.ServiceModel.Message を作成します。

BodyWriter の実装

次の例は、ノード値ストリーミングを実行する BodyWriter の実装を示しています。

/// <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  
}  

BodyWriter を使用してメッセージを作成する

次の例は、前の例の BodyWriter を使用して SendIdoc 要求メッセージを作成する方法を示しています。 メッセージ データはファイルから読み取られます。

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);  
  

アダプターからのインバウンド Flat-File IDOC のストリーミング

受信の "ReceiveIdoc" 操作でフラットファイル形式のIDOCを受け取ります。 アダプターは、ReceiveIdoc 操作の要求メッセージでノード値ストリーミングをサポートします。

WCF チャネル モデルの ReceiveIdoc 操作でノード値ストリーミングをサポートするには、次の操作を行う必要があります。

  1. IDOC データをストリーミングできる System.Xml.Xml.XmlDictionaryWriter を実装します (IDOC データでノード値ストリーミングを実行します)。

  2. このXmlDictionaryWriterメッセージWriteBodyContentsメソッドを呼び出して処理します。

XmlDictionaryWriter の実装

次の例は、ノード値ストリーミングを実行する XmlDictionaryWriter の実装を示しています。

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; }  
    }  
  
}  

XmlDictionaryWriter を使用したメッセージの消費

次の例は、前の例で実装した FileXmlWriter を使用して ReceiveIdoc 要求メッセージを使用する方法を示しています。 ( FileWriter クラスは、 XmlDictionaryWriter のサブクラスによって作成されました)。この例では、 IReplyChannel チャネルを使用して ReceiveIdoc 操作を受信します。 チャネル作成の詳細は省略されています。 ReceiveIdoc 要求メッセージがファイルに書き込まれます。

// 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();  
  

こちらもご覧ください

WCF チャネル モデルを使用してアプリケーションを開発する