Envío de IDOC a SAP mediante el modelo de servicio WCF
Internamente, el adaptador de Microsoft BizTalk para mySAP Business Suite envía IOC al sistema SAP invocando una de las dos RFC siguientes:
IDOC_INBOUND_ASYNCHRONOUS para IDOC de la versión 3.
INBOUND_IDOC_PROCESS para las IDOC de la versión 2.
Puede enviar un IDOC al adaptador invocando el RFC adecuado (o tRFC); Sin embargo, también puede usar las dos operaciones siguientes para enviar IDOC al adaptador:
SendIdoc aparece directamente bajo el nodo raíz del IDOC. La operación SendIdoc envía el IDOC como datos de cadena (con tipo débil) al adaptador de SAP.
El envío se muestra individualmente para cada IDOC. La operación Send envía el IDOC como datos fuertemente tipados al adaptador de SAP.
Estas operaciones determinan cómo se envían los datos del IDOC al adaptador, no cómo se envían al sistema SAP. El adaptador siempre envía el IDOC al sistema SAP mediante el tRFC adecuado.
Dado que el adaptador de SAP envía el IDOC como tRFC, las operaciones Send y SendIdoc exponen un parámetro GUID que se usa para confirmar (confirmar) el IDOC. El adaptador de SAP asigna internamente este GUID con el identificador de transacción de SAP (TID) asociado al tRFC. Puede confirmar el IDOC de una de estas dos maneras:
Mediante el uso de la propiedad de enlace AutoConfirmSentIdocs . Si esta propiedad de enlace se establece en true, el adaptador confirma automáticamente el tRFC usado para enviar el IDOC.
Invocando RfcConfirmTransID. Invoque esta operación con el GUID asociado al IDOC.
En las secciones siguientes se muestra cómo enviar IDC a un sistema SAP mediante las operaciones SendIdoc y Send. Para obtener más información que le ayude a enviar un IDOC como tRFC, vea Invocar tRFC en SAP mediante el modelo de servicio WCF.
La clase de cliente WCF
Operación SendIdoc
El adaptador de SAP muestra una sola operación (y contrato de servicio) para enviar un IDOC en formato de cadena. El nombre del contrato de servicio es "Idoc" y la clase de cliente WCF es IdocClient.
Puede enviar cualquier IDOC a SAP mediante este cliente. Contiene un único método, SendIdoc, que toma dos parámetros:
idocData es una cadena que contiene los datos de IDOC.
guid es el GUID que se asigna a la TID de SAP.
En el código siguiente se muestra el cliente WCF que se genera para la operación SendIdoc.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class IdocClient : System.ServiceModel.ClientBase<Idoc>, Idoc {
public void SendIdoc(string idocData, ref System.Nullable\<System.Guid\> guid) {…}
}
Operación de envío
Dado que la operación De envío usa datos fuertemente tipados, el adaptador de SAP muestra un contrato de servicio único para cada IDOC. El nombre de la interfaz (y la clase de cliente WCF) generada para este contrato se basa en el tipo IDOC, la versión, el número de versión y el tipo CIM (si procede). Por ejemplo, para el IDOC ORDERS03.v3.620, la interfaz se denomina "IdocORDERS03V3R620" y la clase de cliente WCF es IdocORDERS03V3R620Client.
Debe generar un cliente único para cada tipo de IDOC diferente. Este cliente contiene un único método, Send, que toma dos parámetros:
idocData es una clase que representa los datos IDOC fuertemente tipados.
guid es una representación de cadena del GUID que se asigna al TID de SAP.
En el código siguiente se muestra el cliente WCF que se genera para la operación Send expuesta para el IDOC ORDERS03.v3.620.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class IdocORDERS03V3R620Client : System.ServiceModel.ClientBase<IdocORDERS03V3R620>, IdocORDERS03V3R620 {
...
public void Send(ORDERS03 idocData, ref string guid) { ... }
}
Cómo crear una aplicación para enviar IDOC
Para enviar un IDOC a un sistema SAP, realice los pasos siguientes.
Para enviar un IDOC a un sistema SAP
Genere una clase de cliente WCF. Use el complemento Agregar referencia del servicio adaptador de Visual Studio o la Herramienta de utilidad de metadatos serviceModel (svcutil.exe) para generar la clase de cliente WCF que tiene como destino las IDOC con las que desea trabajar. Para obtener más información sobre cómo generar un cliente WCF, consulte Generación de un cliente WCF o un contrato de servicio WCF para artefactos de solución de SAP. Si desea confirmar explícitamente IDC, asegúrese de generar el cliente WCF para la operación RfcConfirmTransID. Las operaciones se pueden encontrar en los nodos siguientes:
Operación SendIdoc. Directamente bajo el nodo IDOC.
Operación de envío. En el nodo correspondiente al tipo, versión y número de versión del IDOC de destino.
Operación RfcConfirmTransID. Directamente bajo el nodo TRFC.
Cree una instancia de la clase de cliente WCF generada en el paso 1 y especifique un enlace de cliente. Especificar un enlace de cliente implica especificar el enlace y la dirección del punto de conexión que usará el cliente WCF. Puede hacerlo de forma imperativa en el código o mediante declaración en la configuración. Para obtener más información sobre cómo especificar un enlace de cliente, vea Configurar un enlace de cliente para el sistema SAP. El código siguiente inicializa un IdocClient (para la operación de envío) desde la configuración y establece las credenciales para el sistema SAP.
SAPBinding binding = new SAPBinding(); // Set endpoint address EndpointAddress endpointAddress = new EndpointAddress("sap://CLIENT=800;LANG=EN;@a/YourSAPHost/00?RfcSdkTrace=False&AbapDebug=False&UseSapGui=Without"); // Create client and set credentials idocClient = new IdocClient(binding, endpointAddress); idocClient.ClientCredentials.UserName.UserName = "YourUserName"; idocClient.ClientCredentials.UserName.Password = "YourPassword";;
Si desea que el adaptador confirme el tRFC en el sistema SAP después de enviar el IDOC, establezca la propiedad de enlace AutoConfirmSentIdocs en true. Debe hacerlo antes de abrir el cliente WCF.
// Set AutoConfirmSentIdocs property to true binding.AutoConfirmSentIdocs = true;
Abra el cliente WCF.
idocClient.Open();
Invoque el método adecuado en el cliente WCF creado en el paso 2 para enviar el IDOC al sistema SAP. Puede pasar una variable que contenga un GUID o que esté establecido en NULL para el parámetro guid . Si no especifica un GUID, el adaptador de SAP genera uno para la operación (guid es un parámetro ref ). El código siguiente lee un IDOC (en formato de cadena) de un archivo y lo envía al sistema SAP mediante la operación SendIdoc.
// Read IDOC into string variable using (StreamReader reader = new StreamReader("ORDERS03.txt")) { idocData = reader.ReadToEnd(); } //Get a new GUID to pass to SendIdoc. You can also assign a null //value to have the adapter generate a GUID. adapterTxGuid = Guid.NewGuid(); //Invoke SendIdoc on the client to send the IDOC to the SAP system idocClient.SendIdoc(idocData, ref adapterTxGuid);
Si no estableció la propiedad de enlace AutoConfirmSentIdocs en true (en el paso 3), debe confirmar el tRFC en el sistema SAP. Para ello, debe invocar el método RfcConfirmTransID en un TrfcClient (no se muestra la creación). Especifique el GUID devuelto en el paso 4 para el parámetro .
trfcClient.RfcConfirmTransID(adapterTxGuid);
Cierre el cliente WCF (y TrfcClient, si se usa) cuando haya terminado de usarlo (una vez que haya terminado de enviar IDOC).
idocClient.Close();
Ejemplo
En el ejemplo siguiente se envía un IDOC a un sistema SAP mediante el método SendIdoc. El IDOC se lee desde un archivo, ORDERS03.txt. Este archivo contiene un ORDERS03. IDOC V3.620 y se incluye con las muestras; Sin embargo, la operación SendIdoc se puede usar para enviar cualquier IDOC.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
// Add WCF, WCF LOB Adapter SDK, and SAP adapter namepaces
using System.ServiceModel;
using Microsoft.Adapters.SAP;
using Microsoft.ServiceModel.Channels;
// Include this namespace for WCF LOB Adapter SDK and SAP exceptions
using Microsoft.ServiceModel.Channels.Common;
// This example sends a flat IDOC to the SAP system by using the SendIdoc operation.
namespace SapIdocStringClientSM
{
class Program
{
static void Main(string[] args)
{
// variable for the IDOC client
IdocClient idocClient = null;
Console.WriteLine("IDOC string client sample started");
try
{
// Variable for the GUID
System.Nullable<System.Guid> adapterTxGuid;
// string to hold the Idoc data
string idocData;
// string to hold the SAP transaction ID (TID)
string sapTxId;
// The client can be configured from app.config, but it is
// explicitly configured here for demonstration.
// set AutoConfirmSentIdocs property to true
SAPBinding binding = new SAPBinding();
binding.AutoConfirmSentIdocs = true;
// Set endpoint address
EndpointAddress endpointAddress = new EndpointAddress("sap://CLIENT=800;LANG=EN;@a/YourSAPServer/00?RfcSdkTrace=False&AbapDebug=False&UseSapGui=Without");
// Create client and set credentials
idocClient = new IdocClient(binding, endpointAddress);
idocClient.ClientCredentials.UserName.UserName = "YourUserName";
idocClient.ClientCredentials.UserName.Password = "YourPassword";
// Open the client and send the Idoc
idocClient.Open();
// Read IDOC into string variable
using (StreamReader reader = new StreamReader("ORDERS03.txt"))
{
idocData = reader.ReadToEnd();
}
//Get a new GUID to pass to SendIdoc. You can also assign a null.
//value to have the adapter generate a GUID.
adapterTxGuid = Guid.NewGuid();
//Invoke SendIdoc on the client to send the IDOC to the SAP system.
idocClient.SendIdoc(idocData, ref adapterTxGuid);
// The AutoConfirmSentIdocs binding property is set to true, so there is no need to
// confirm the IDOC. If this property is not set to true, you must call the
// RfcConfirmTransID method of a TrfcClient with adapterTxGuid to
// confirm the transaction on the SAP system.
// Get SAP tx id from GUID
sapTxId = SAPAdapterUtilities.ConvertGuidToTid((Guid) adapterTxGuid);
Console.WriteLine("IDOC sent");
Console.WriteLine("The SAP Transaction Id is : " + sapTxId);
catch (Exception ex)
{
Console.WriteLine("Exception is: " + ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);
}
}
finally
{
// Close the IDOC client
if (idocClient != null)
{
if (idocClient.State == CommunicationState.Opened)
idocClient.Close();
else
idocClient.Abort();
}
}
}
}
}