Partager via


Stream Flat-File IDOCs dans SAP à l’aide du modèle de canal WCF

L’adaptateur Microsoft BizTalk pour mySAP Business Suite prend en charge le streaming à valeur de nœud pour les opérations SendIdoc et ReceiveIdoc. Ces opérations sont utilisées pour envoyer et recevoir des IDOCs de type flat-file (chaîne de caractères) vers et depuis l’adaptateur. Dans ces deux opérations, les données de l’ensemble de l’IDOC sont contenues dans une chaîne sous un seul nœud (<idocData>). Pour les IDOCs volumineux, la diffusion en continu des données IDOC entre l’adaptateur et votre code peut économiser des ressources de mémoire importantes.

Pour plus d’informations sur la façon dont l’adaptateur prend en charge la diffusion en continu, consultez Streaming et adaptateur SAP. Vous devez lire cette rubrique avant de continuer.

Les sections de cette rubrique décrivent comment implémenter le streaming à valeur de nœud pour les opérations SendIdoc et ReceiveIdoc lorsque vous utilisez le modèle de canal WCF.

Streaming Outbound Flat-File IDOCs vers l’adaptateur

L’adaptateur prend en charge la diffusion du flux des valeurs de nœud sur le message de requête pour l’opération SendIdoc.

Pour prendre en charge la diffusion en continu des valeurs de nœud sur les opérations SendIdoc dans le modèle de canal WCF, vous devez :

  1. Implémentez un System.ServiceModel.Channels.BodyWriter capable de diffuser en continu les données IDOC (exécution d’un streaming à valeur de nœud sur les données IDOC).

  2. Créez le System.ServiceModel.Message utilisé pour invoquer l'opération en fournissant le corps du message grâce à ce BodyWriter, en utilisant une surcharge appropriée de la méthode Message.Create.

Implémentation d’un BodyWriter

L’exemple suivant montre une implémentation d’un BodyWriter qui effectue un streaming à valeur de nœud.

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

Création d’un message à l’aide d’un BodyWriter

L’exemple suivant montre comment créer un message de requête SendIdoc à l’aide de BodyWriter dans l’exemple précédent. Les données de message sont lues à partir d’un fichier.

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 entrant Flat-File IDOCs à partir de l’adaptateur

Vous recevez un IDOC de fichier plat dans l'opération ReceiveIdoc entrante. L’adaptateur prend en charge la diffusion en continu des valeurs de nœud sur le message de requête pour l’opération ReceiveIdoc.

Pour assurer la prise en charge du streaming des valeurs de nœud lors des opérations ReceiveIdoc dans le modèle de canal WCF, vous devez :

  1. Implémentez un System.Xml.XmlDictionaryWriter capable de diffuser en continu les données IDOC (exécution d’un streaming à valeur de nœud sur les données IDOC).

  2. Consommez le Message en appelant sa méthode WriteBodyContents avec ce XmlDictionaryWriter.

Implémentation d’un XmlDictionaryWriter

L’exemple suivant montre une implémentation d’un XmlDictionaryWriter qui effectue un flux de valeurs de nœud.

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

Consommation d’un message à l’aide d’un XmlDictionaryWriter

L’exemple suivant montre comment utiliser un message de requête ReceiveIdoc à l’aide de FileXmlWriter implémenté dans l’exemple précédent. (La classe FileWriter a été créée par la sous-classe XmlDictionaryWriter.) L’exemple utilise un canal IReplyChannel pour recevoir l’opération ReceiveIdoc. Les détails de la création du canal ont été omis. Le message de requête ReceiveIdoc est écrit dans un fichier.

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

Voir aussi

Développer des applications à l’aide du modèle de canal WCF