Compartir a través de


Transmisión de Flat-File IFC en SAP mediante el modelo de canal WCF

El adaptador de Microsoft BizTalk para mySAP Business Suite admite el streaming de valor de nodo para las operaciones SendIdoc y ReceiveIdoc. Estas operaciones se usan para enviar y recibir IOC de archivo plano (cadena) hacia y desde el adaptador. En ambas operaciones, los datos de todo el IDOC se encuentran en una cadena bajo un único nodo (<idocData>). En el caso de los IDOC grandes, el streaming de los datos del IDOC entre el adaptador y el código puede ahorrar recursos de memoria significativos.

Para obtener información general sobre cómo admite el adaptador de streaming, consulte Streaming y el adaptador de SAP. Debe leer este tema antes de continuar.

En las secciones de este tema se describe cómo implementar el streaming de valores de nodo para las operaciones SendIdoc y ReceiveIdoc al usar el modelo de canal WCF.

Streaming de Flat-File IDC de salida al adaptador

El adaptador admite la transmisión por secuencias de valor de nodo en el mensaje de solicitud para la operación SendIdoc.

Para admitir el streaming de valores de nodo en las operaciones SendIdoc en el modelo de canal WCF, debe hacer lo siguiente:

  1. Implemente un System.ServiceModel.Channels.BodyWriter que sea capaz de transmitir los datos de IDOC (realizando streaming de valor de nodo en los datos de IDOC).

  2. Cree el objeto System.ServiceModel.Message que se usa para invocar la operación proporcionando el cuerpo del mensaje con bodyWriter mediante una sobrecarga adecuada del método Message.Create .

Implementación de BodyWriter

En el ejemplo siguiente se muestra una implementación de bodyWriter que realiza el streaming de valores de nodo.

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

Creación de un mensaje mediante BodyWriter

En el ejemplo siguiente se muestra cómo crear un mensaje de solicitud SendIdoc mediante BodyWriter en el ejemplo anterior. Los datos del mensaje se leen desde un archivo.

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 inbound Flat-File IDOC desde el adaptador

Recibirá un ARCHIVO PLANO en la operación ReceiveIdoc de entrada. El adaptador admite el streaming de nodo-valor en el mensaje de solicitud para la operación ReceiveIdoc.

Para admitir el streaming de valores de nodo en las operaciones ReceiveIdoc en el modelo de canal WCF, debe hacer lo siguiente:

  1. Implemente un System.Xml. XmlDictionaryWriter que es capaz de transmitir los datos de IDOC (realizando streaming de valor de nodo en los datos del IDOC).

  2. Use el mensaje invocando su método WriteBodyContents con este XmlDictionaryWriter.

Implementación de xmlDictionaryWriter

En el ejemplo siguiente se muestra una implementación de xmlDictionaryWriter que realiza el streaming de valores de nodo.

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

Consumo de un mensaje mediante xmlDictionaryWriter

En el ejemplo siguiente se muestra cómo consumir un mensaje de solicitud ReceiveIdoc mediante FileXmlWriter implementado en el ejemplo anterior. (La clase FileWriter se creó mediante la subclase XmlDictionaryWriter). En el ejemplo se usa un canal IReplyChannel para recibir la operación ReceiveIdoc. Se han omitido los detalles de la creación del canal. El mensaje de solicitud ReceiveIdoc se escribe en un archivo.

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

Consulte también

Desarrollar aplicaciones con el modelo de canal WCF