Partager via


Appeler des opérations sur le système SAP à l’aide du modèle de canal WCF

Vous appelez des opérations sur l’adaptateur SAP à l’aide d’une forme de canal IRequestChannel ou IOutputChannel pour envoyer des messages à l’adaptateur. Le modèle de base consiste à créer une fabrique de canaux pour la forme de canal requise à l’aide d’une liaison (SAPBinding) et d’un point de terminaison créé à partir d’un URI de connexion. Vous créez ensuite un message instance qui représente un message SOAP conforme au schéma de message pour votre opération cible. Vous pouvez ensuite envoyer ce message à l’adaptateur SAP à l’aide d’un canal créé à partir de la fabrique de canaux. Si vous utilisez un IRequestChannel, vous recevez une réponse. En cas de problème lors de l’exécution de l’opération sur le système SAP, l’adaptateur SAP lève une exception Microsoft.ServiceModel.Channels.Common.TargetSystemException.

Pour obtenir une vue d’ensemble de l’envoi d’opérations à l’aide d’un IRequestChannel dans WCF, consultez Programmation de Channel-Level client.

Les sections de cette rubrique fournissent des informations pour vous aider à appeler des opérations sur l’adaptateur SAP à l’aide du modèle de canal WCF.

Prise en charge des transactions BAPI dans le modèle de canal WCF

Tous les BAPI qui sont appelés à l’aide de la même connexion SAP font partie de la même unité logique de travail (LUW) (ou transaction) sur le système SAP. Chaque canal WCF représente une connexion unique au système SAP. Pour prendre en charge les transactions BAPI à l’aide du modèle de canal WCF :

  • Assurez-vous que chaque BAPI dans une transaction LUW (transaction) est envoyée sur le même canal. Cela inclut l’BAPI_TRANSACTION COMMIT ou les opérations BAPI_TRANSACTION_ROLLBACK.

  • Veillez à fermer tout message de réponse reçu pour un BAPI avant d’appeler le suivant BAPI sur le canal. (Vous devez effectuer cette opération pour chaque opération, mais cela est particulièrement important pour les API BAP.)

    Pour plus d’informations sur les transactions BAPI, consultez Opérations sur les BAPI dans SAP.

Diffusion en continu d’AIDO de fichiers plats vers l’adaptateur SAP

Vous utilisez l’opération SendIdoc pour envoyer un IDOC de fichier plat (chaîne) à l’adaptateur. Les données IDOC sont représentées sous la forme d’une chaîne sous un nœud unique dans cette opération. Pour cette raison, l’adaptateur SAP prend en charge la diffusion en continu de valeur de nœud sur le message de demande. Pour effectuer une diffusion en continu de valeur de nœud, vous devez créer le message de demande pour l’opération SendIdoc à l’aide d’un System.ServiceModel.Channels.BodyWriter capable de diffuser en continu les données IDOC. Pour plus d’informations sur la procédure à suivre, consultez Streaming Flat-File IDOCs dans SAP à l’aide du modèle de canal WCF.

Comment appeler une opération à l’aide d’un canal ?

Pour appeler une opération à l’aide d’un IRequestChannel, procédez comme suit.

Comment appeler une opération à l’aide d’un instance de IRequestChannel

  1. Créez une fabrique de canaux (ChannelFactory<IRequestChannel>). Pour ce faire, vous devez spécifier une liaison (SAPBinding) et une adresse de point de terminaison. Vous pouvez spécifier la liaison et l’adresse de point de terminaison de manière impérative dans votre code ou de manière déclarative dans la configuration. Vous devez définir toutes les propriétés de liaison requises pour les opérations que vous allez envoyer avant d’ouvrir la fabrique. Pour plus d’informations sur la façon de spécifier la liaison et l’adresse de point de terminaison dans la configuration, consultez Créer un canal à l’aide de SAP.

    // Create a binding  
    SAPBinding binding = new SAPBinding();  
    // Create an endpoint address by using the connection URI  
    EndpointAddress endpointAddress = new EndpointAddress("sap://Client=800;lang=EN@A/YourSAPHost/00");  
    // Create the channel factory  
    ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(binding, address);  
    
  2. Définissez les informations d’identification du mot de passe de nom d’utilisateur pour la fabrique de canaux à l’aide de la propriété ClientCredentials .

    factory.Credentials.UserName.UserName = "YourUserName";  
    factory.Credentials.UserName.Password = "YourPassword";  
    
  3. Ouvrez la fabrique de canal.

    factory.Open();  
    
  4. Obtenez un canal à partir de la fabrique et ouvrez-le.

    IRequestChannel channel = factory.CreateChannel();  
    channel.Open();  
    
  5. Créez un message instance pour l’opération cible. Assurez-vous que l’action de message pour l’opération cible est spécifiée. Dans cet exemple, le corps du message est passé en créant un XmlReader sur une chaîne. L’opération cible appelle le SD_RFC_CUSTOMER_GET RFC sur un système SAP.

    string inputXml = "\<SD_RFC_CUSTOMER_GET xmlns="http://Microsoft.LobServices.Sap/2007/03/Rfc/\"> <KUNNR i:nil=\"true\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"> </KUNNR> <NAME1>AB*</NAME1> <CUSTOMER_T> </CUSTOMER_T> </SD_RFC_CUSTOMER_GET>";  
    
    //create an XML reader from the input XML  
    XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.Default.GetBytes(inputXml)));  
    
    //create a WCF message from our XML reader  
    Message inputMessge = Message.CreateMessage(MessageVersion.Soap11, "http://Microsoft.LobServices.Sap/2007/03/Rfc/SD_RFC_CUSTOMER_GET", reader);  
    
  6. Appelez la méthode Request sur le canal pour envoyer le message à l’adaptateur SAP et recevoir la réponse. Si le système SAP rencontre une exception, l’adaptateur lève une exception TargetSystemException. (D’autres exceptions sont possibles pour les exceptions non SAP.) Vous pouvez obtenir une description de l’erreur SAP à partir de la propriété InnerException.Message de l’objet TargetSystemException.

    try  
    {  
        Message messageOut = channel.Request(messageIn);  
    }  
    catch (Exception ex)  
    {  
        // handle exception  
    }  
    
  7. Traitez la réponse. Dans cet exemple, GetReaderAtBodyContents est appelé sur le message de réponse pour obtenir le corps du message.

    XmlReader readerOut = messageOut.GetReaderAtBodyContents();  
    
  8. Lorsque vous avez terminé de traiter le message de réponse, fermez le lecteur et le message.

    readerOut.Close();  
    messageOut.Close();  
    
  9. Lorsque vous avez terminé d’utiliser le canal et la fabrique de canal, fermez-les. La fermeture de la fabrique ferme tous les canaux qui ont été créés avec elle.

    channel.Close()  
    factory.Close();  
    
  10. Vous suivez les mêmes étapes pour envoyer un message à l’aide de la forme IOutputChannel , sauf :

  • Vous créez un canal ChannelFactory<IOutputChannel> à l’étape 1.

  • Vous appelez la méthode Send sur le canal à l’étape 6. channel.Send(messageIn);.

  • Aucun message de réponse n’est retourné pour un IOutputChannel.

Exemple

L’exemple suivant montre comment appeler une RFC à l’aide d’un canal IRequestChannel . Cet exemple appelle le SD_RFC_CUSTOMER_GET RFC pour obtenir la liste des clients dont le nom commence par « AB ». Le message de réponse est consommé à l’aide d’un XmlReader et le numéro de client et le nom de chaque client retournés sont écrits dans la console.

using System;  
using System.Collections.Generic;  
using System.Text;  
  
using System.Xml;  
using System.IO;  
  
using System.ServiceModel;  
using Microsoft.Adapters.SAP;  
using Microsoft.ServiceModel.Channels;  
using System.ServiceModel.Channels;  
  
namespace SapRfcClientCM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            //create a binding  
            SAPBinding binding = new SAPBinding();  
  
            //set up an endpoint address.  
            EndpointAddress endpointAddress = new EndpointAddress("sap://Client=800;lang=EN@A/YourSAPHost/00");  
  
            //create a channel factory, capable of sending a request to SAP and receiving a reply (IRequestChannel)  
            ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(binding, endpointAddress);  
  
            // add credentials  
            factory.Credentials.UserName.UserName = "YourUserName";  
            factory.Credentials.UserName.Password = "YourPassword";  
  
            //open the factory  
            factory.Open();  
  
            //obtain a channel from the factory by specifying the address you want to connect to  
            IRequestChannel channel = factory.CreateChannel();  
  
            //open the channel  
            channel.Open();  
  
            //create an XML message to send to the SAP system  
            //We are invoking the SD_RFC_CUSTOMER_GET RFC.  
            //The XML below specifies that we want to search for customers with names starting with "AB"  
            string inputXml = "<SD_RFC_CUSTOMER_GET xmlns=\"http://Microsoft.LobServices.Sap/2007/03/Rfc/\"> <KUNNR i:nil=\"true\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"> </KUNNR> <NAME1>AB*</NAME1> <CUSTOMER_T> </CUSTOMER_T> </SD_RFC_CUSTOMER_GET>";  
  
            //create an XML reader from the input XML  
            XmlReader readerOut = XmlReader.Create(new MemoryStream(Encoding.Default.GetBytes(inputXml)));  
  
            //create a WCF message from the XML reader  
            Message messageOut = Message.CreateMessage(MessageVersion.Default, "http://Microsoft.LobServices.Sap/2007/03/Rfc/SD_RFC_CUSTOMER_GET", readerOut);  
  
            //send the message to SAP and obtain a reply  
            Message messageIn = channel.Request(messageOut);  
  
            // Write the KUNNR and NAME1 fields for each returned record to the Console  
            Console.WriteLine("Results of SD_RFC_CUSTOMER_GET");  
            Console.WriteLine("KUNNR\t\tNAME1");  
  
            XmlReader readerIn = messageIn.GetReaderAtBodyContents();  
  
            while (readerIn.Read())  
            {  
                if (readerIn.IsStartElement())  
                {  
                    switch (readerIn.Name)  
                    {  
                        case "RFCCUST":  
                            Console.Write("\n");  
                            break;  
  
                        case "KUNNR":  
                            readerIn.Read();  
                            Console.Write(readerIn.ReadString() + "\t");  
                            break;  
  
                        case "NAME1":  
                            readerIn.Read();  
                            Console.Write(readerIn.ReadString() + "\t");  
                            break;  
  
                        default:  
                            break;  
                    }  
                }  
            }  
  
            // return the cursor  
            Console.WriteLine();  
  
            // Close the input reader  
            readerIn.Close();  
  
            // Close the input message. You should do this for every message you   
            // send on the channel  
            messageIn.Close();  
  
            // close the channel when you are done using it.  
            channel.Close();  
  
            //close the factory  
            //note: closing the factory will close all of its channels.  
            factory.Close();  
        }  
    }  
}  

Voir aussi

Développer des applications en utilisant le modèle de canal WCF