Condividi tramite


Trasmettere Flat-File IDOC in SAP usando il modello di canale WCF

L'adapter Microsoft BizTalk per mySAP Business Suite supporta lo streaming node-value per le operazioni SendIdoc e ReceiveIdoc. Queste operazioni vengono usate per inviare e ricevere IDOC (string) flat-file da e verso l'adapter. In entrambe queste operazioni, i dati per l'intero IDOC sono contenuti in una stringa in un singolo nodo (<idocData>). Per i IDOC di grandi dimensioni, lo streaming dei dati IDOC tra l'adattatore e il codice possono salvare risorse di memoria significative.

Per informazioni in background sul modo in cui l'adapter supporta lo streaming, vedere Streaming e l'adapter SAP. È necessario leggere questo argomento prima di procedere.

Le sezioni di questo argomento descrivono come implementare lo streaming node-value per le operazioni SendIdoc e ReceiveIdoc quando si usa il modello di canale WCF.

Streaming in uscita Flat-File IDOCs nell'adapter

L'adapter supporta lo streaming node-value nel messaggio di richiesta per l'operazione SendIdoc.

Per supportare lo streaming node-value nelle operazioni SendIdoc nel modello di canale WCF, è necessario:

  1. Implementare un oggetto System.ServiceModel.Channels.BodyWriter in grado di trasmettere i dati IDOC (che eseguono lo streaming di nodi sui dati IDOC).

  2. Creare system.ServiceModel.Message usato per richiamare l'operazione fornendo il corpo del messaggio con questo BodyWriter usando un overload appropriato del metodo Message.Create .

Implementazione di un BodyWriter

Nell'esempio seguente viene illustrata un'implementazione di BodyWriter che esegue lo streaming node-value.

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

Creazione di un messaggio usando bodywriter

Nell'esempio seguente viene illustrato come creare un messaggio di richiesta SendIdoc usando BodyWriter nell'esempio precedente. I dati del messaggio sono letti da un file.

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 di Flat-File IDOC in ingresso dall'adapter

Viene visualizzato un IDOC file flat nell'operazione ReceiveIdoc in ingresso. L'adapter supporta lo streaming node-value nel messaggio di richiesta per l'operazione ReceiveIdoc.

Per supportare lo streaming node-value nelle operazioni ReceiveIdoc nel modello di canale WCF, è necessario:

  1. Implementare un System.Xml. XmlDictionaryWriter in grado di trasmettere i dati IDOC (esecuzione dello streaming dei valori del nodo nei dati IDOC).

  2. Utilizzare il messaggio richiamando il metodo WriteBodyContents con questo oggetto XmlDictionaryWriter.

Implementazione di un oggetto XmlDictionaryWriter

Nell'esempio seguente viene illustrata un'implementazione di un oggetto XmlDictionaryWriter che esegue lo streaming node-value.

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

Utilizzo di un messaggio tramite xmlDictionaryWriter

Nell'esempio seguente viene illustrato come usare un messaggio di richiesta ReceiveIdoc usando FileXmlWriter implementato nell'esempio precedente. La classe FileWriter è stata creata con sottoclasse XmlDictionaryWriter. Nell'esempio viene usato un canale IReplyChannel per ricevere l'operazione ReceiveIdoc. I dettagli della creazione del canale sono stati omessi. Il messaggio di richiesta ReceiveIdoc viene scritto in un file.

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

Vedere anche

Sviluppare applicazioni tramite il modello di canale WCF