Inviare IDOCs a SAP usando il modello di servizio WCF
Internamente, l'adapter Microsoft BizTalk per mySAP Business Suite invia IDOCs al sistema SAP richiamando una delle due schede di rete seguenti:
IDOC_INBOUND_ASYNCHRONOUS per i IDOC versione 3.
INBOUND_IDOC_PROCESS per IDOCs versione 2.
È possibile inviare un IDOC all'adattatore richiamando il RFC (o tRFC appropriato); Tuttavia, è anche possibile usare le due operazioni seguenti per inviare IDOCs all'adapter:
SendIdoc viene eseguito direttamente sotto il nodo radice IDOC. L'operazione SendIdoc invia i dati IDOC come stringa (tipizzata in modo debole) all'adapter SAP.
L'invio viene superficieto singolarmente per ogni IDOC. L'operazione Send invia il IDOC come dati fortemente tipizzato all'adapter SAP.
Queste operazioni determinano il modo in cui i dati IDOC vengono inviati all'adattatore, non come vengono inviati al sistema SAP. L'adattatore invia sempre l'IDOC al sistema SAP usando il tRFC appropriato.
Poiché l'adapter SAP invia IDOC come TRFC, le operazioni Send e SendIdoc espongono un parametro GUID usato per confermare (commit) l'IDOC. L'adapter SAP esegue internamente il mapping di questo GUID con l'ID transazione SAP (TID) associato al tRFC. È possibile confermare l'IDOC in uno dei due modi seguenti:
Usando la proprietà di associazione AutoConfirmSentIdocs . Se questa proprietà di associazione è impostata su true, l'adapter conferma automaticamente l'oggetto tRFC usato per inviare il file IDOC.
Richiamando RfcConfirmTransID. Si richiama questa operazione con il GUID associato all'IDOC.
Le sezioni seguenti illustrano come inviare IDOCs a un sistema SAP usando le operazioni SendIdoc e Send. Per altre informazioni sull'invio di un IDOC come TRFC, vedere Richiamare tRFCS in SAP usando il modello di servizio WCF.
Classe client WCF
Operazione SendIdoc
L'adattatore SAP visualizza una singola operazione (e un contratto di servizio) per inviare un IDOC in formato stringa. Il nome del contratto di servizio è "Idoc" e la classe client WCF è IdocClient.
È possibile inviare qualsiasi IDOC a SAP usando questo client. Contiene un singolo metodo , SendIdoc, che accetta due parametri:
idocData è una stringa che contiene i dati IDOC
guid è il GUID mappato a SAP TID.
Il codice seguente mostra il client WCF generato per l'operazione 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) {…}
}
Operazione di invio
Poiché l'operazione di invio usa dati fortemente tipizzato, l'adattatore SAP visualizza un contratto di servizio univoco per ogni IDOC. Il nome dell'interfaccia (e della classe client WCF) generato per questo contratto è basato sul tipo IDOC, sulla versione, sul numero di versione e sul tipo CIM (se pertinente). Ad esempio, per l'IDOC ORDERS03.v3.620, l'interfaccia è denominata " IdocORDERS03V3R620" e la classe client WCF è IdocORDERS03V3R620Client.
È necessario generare un client univoco per ogni tipo diverso di IDOC. Questo client contiene un singolo metodo, Send, che accetta due parametri:
idocData è una classe che rappresenta i dati IDOC fortemente tipizzato.
guid è una rappresentazione di stringa del GUID mappato a SAP TID.
Il codice seguente mostra il client WCF generato per l'operazione di invio per l'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) { ... }
}
Come creare un'applicazione per inviare IDOCs
Per inviare un IDOC a un sistema SAP, seguire questa procedura.
Per inviare un IDOC a un sistema SAP
Generare una classe client WCF. Usare il plug-in Add Adapter Service Reference Visual Studio o serviceModel Metadata Utility Tool (svcutil.exe) per generare la classe client WCF destinata ai IDOCs con cui si desidera lavorare. Per altre informazioni su come generare un client WCF, vedere Generazione di un client WCF o di un contratto di servizio WCF per gli artefatti della soluzione SAP. Se si desidera confermare in modo esplicito IDOCs, assicurarsi di generare il client WCF per l'operazione RfcConfirmTransID. Le operazioni sono disponibili nei nodi seguenti:
Operazione SendIdoc. Direttamente nel nodo IDOC.
Operazione di invio. Nel nodo corrispondente al tipo, versione e numero di rilascio del codice IDOC di destinazione.
Operazione RfcConfirmTransID. Direttamente sotto il nodo TRFC.
Creare un'istanza della classe client WCF generata nel passaggio 1 e specificare un'associazione client. Se si specifica un'associazione client, è necessario specificare l'indirizzo dell'associazione e dell'endpoint che verrà usato dal client WCF. È possibile eseguire questa operazione in modo imperativo nel codice o in modo dichiarativo nella configurazione. Per altre informazioni su come specificare un'associazione client, vedere Configurare un'associazione client per il sistema SAP. Il codice seguente inizializza un IdocClient (per l'operazione di invio) dalla configurazione e imposta le credenziali per il 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";;
Se si vuole che l'adattatore verifichi il tRFC nel sistema SAP dopo aver inviato il file IDOC, impostare la proprietà di associazione AutoConfirmSentIdocs su true. Prima di aprire il client WCF, è necessario eseguire questa operazione.
// Set AutoConfirmSentIdocs property to true binding.AutoConfirmSentIdocs = true;
Aprire il client WCF.
idocClient.Open();
Richiamare il metodo appropriato nel client WCF creato nel passaggio 2 per inviare l'IDOC al sistema SAP. È possibile passare una variabile contenente un GUID o impostata su Null per il parametro guid . Se non si specifica un GUID, l'adapter SAP genera uno per l'operazione (guid è un parametro ref ). Il codice seguente legge un IDOC (in formato stringa) da un file e lo invia al sistema SAP usando l'operazione 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);
Se non è stata impostata la proprietà di associazione AutoConfirmSentIdocs su true (nel passaggio 3), è necessario confermare il tRFC nel sistema SAP. A tale scopo, è necessario richiamare il metodo RfcConfirmTransID in un TrfcClient (creazione non visualizzata). Specificare il GUID restituito nel passaggio 4 per il parametro.
trfcClient.RfcConfirmTransID(adapterTxGuid);
Chiudere il client WCF (e TrfcClient, se usato) al termine dell'uso (dopo aver completato l'invio di IDOCs).
idocClient.Close();
Esempio
Nell'esempio seguente viene inviato un IDOC a un sistema SAP usando il metodo SendIdoc. L'IDOC viene letto da un file, ORDERS03.txt. Questo file contiene un ORDERS03. V3.620 IDOC ed è incluso negli esempi; Tuttavia, l'operazione SendIdoc può essere usata per inviare qualsiasi 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();
}
}
}
}
}