Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
El adaptador de Microsoft BizTalk para mySAP Business Suite admite el streaming de valores de nodo para las operaciones SendIdoc y ReceiveIdoc. Estas operaciones se usan para enviar y recibir IDOCs de archivos planos (cadena) con 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.
Procesamiento de IDOCs salientes Flat-File hacia el adaptador
El adaptador admite el streaming de valores de nodo en el mensaje de solicitud para la operación SendIdoc.
Para admitir el streaming de valores de nodo en operaciones SendIdoc en el modelo de canal WCF, debe hacer lo siguiente:
Implante un System.ServiceModel.Channels.BodyWriter capaz de realizar la transmisión de los datos IDOC (realizando streaming por nodos en los datos IDOC).
Cree el objeto System.ServiceModel.Message que se utiliza para invocar la operación mediante una sobrecarga adecuada del método Message.Create, proporcionando el cuerpo del mensaje con este BodyWriter.
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
Recibes un IDOC de archivo plano en la operación de recepción entrante de ReceiveIdoc. El adaptador admite la transmisión de valores de nodo en el mensaje de solicitud para la operación ReceiveIdoc.
Para admitir la transmisión de valores de nodo en las operaciones ReceiveIdoc en el modelo de canal WCF, debe:
Implemente una clase System.Xml.XmlDictionaryWriter capaz de transmitir los datos de IDOC, transmitiendo valores de nodo dentro de los datos de IDOC.
Consuma 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 usando 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();