次の方法で共有


WCF チャネル モデルを使用した SAP システムでの操作の呼び出し

SAP アダプターに対する操作を呼び出すには、 IRequestChannel または IOutputChannel チャネル図形を使用して、アダプターにメッセージを送信します。 基本的なパターンは、バインド (SAPBinding) と接続 URI から作成されたエンドポイントを使用して、必要なチャネル図形のチャネル ファクトリを作成することです。 次に、ターゲット操作の メッセージ スキーマに準拠する SOAP メッセージを表す Message インスタンスを作成します。 その後、チャネル ファクトリから作成されたチャネルを使用して、この メッセージ を SAP アダプターに送信できます。 IRequestChannel を使用している場合は、応答を受け取ります。 SAP システムで操作を実行するときに問題が発生した場合、SAP アダプターは Microsoft.ServiceModel.Channels.Common.TargetSystemException をスローします。

WCF で IRequestChannel を使用して操作を送信する方法の概要については、「 クライアント Channel-Level プログラミング」を参照してください。

このトピックのセクションでは、WCF チャネル モデルを使用して SAP アダプターに対する操作を呼び出すのに役立つ情報を提供します。

WCF チャネル モデルでの BAPI トランザクションのサポート

同じ SAP 接続を使用して呼び出されるすべての BAPI は、SAP システム上の同じ作業論理ユニット (LUW) またはトランザクションの一部です。 各 WCF チャネルは、SAP システムへの一意の接続を表します。 WCF チャネル モデルを使用して BAPI トランザクションをサポートするには:

  • LUW (トランザクション) 内のすべての BAPI が同じチャネル経由で送信されていることを確認します。 これには、BAPI_TRANSACTION COMMIT 操作またはBAPI_TRANSACTION_ROLLBACK操作が含まれます。

  • チャネルで次の BAPI を呼び出す前に、BAPI に対して受信した応答メッセージをすべて閉じてください。 (これはすべての操作に対して行う必要がありますが、BAPI では特に重要です)。

    BAPI トランザクションの詳細については、「 SAP での BAPI に対する操作」を参照してください。

フラット ファイル IDOC を SAP アダプターにストリーミングする

SendIdoc 操作を使用して、フラット ファイル (文字列) IDOC をアダプターに送信します。 IDOC データは、この操作で 1 つのノードの下の文字列として表されます。 このため、SAP アダプターは要求メッセージでノード値ストリーミングをサポートしています。 ノード値ストリーミングを実行するには、IDOC データをストリーミングできる System.ServiceModel.Channels.BodyWriter を使用して、SendIdoc 操作の要求メッセージを作成する必要があります。 これを行う方法については、「 WCF チャネル モデルを使用して SAP で IDOC を Flat-File ストリーミングする」を参照してください。

チャネルを使用して操作を呼び出す方法

IRequestChannel を使用して操作を呼び出すには、次の手順を実行します。

IRequestChannel のインスタンスを使用して操作を呼び出す方法

  1. チャネル ファクトリ (ChannelFactory<IRequestChannel) を構築します>。 これを行うには、バインド (SAPBinding) とエンドポイント アドレスを指定する必要があります。 バインドアドレスとエンドポイント アドレスは、コード内で命令的に指定することも、構成で宣言によって指定することもできます。 ファクトリを開く前に、送信する操作に必要なバインディング プロパティを設定する必要があります。 構成でバインドとエンドポイント アドレスを指定する方法の詳細については、「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. ClientCredentials プロパティを使用して、チャネル ファクトリのユーザー名パスワード資格情報を設定します。

    factory.Credentials.UserName.UserName = "YourUserName";  
    factory.Credentials.UserName.Password = "YourPassword";  
    
  3. チャネル ファクトリを開きます。

    factory.Open();  
    
  4. ファクトリからチャネルを取得して開きます。

    IRequestChannel channel = factory.CreateChannel();  
    channel.Open();  
    
  5. ターゲット操作の Message インスタンスを作成します。 ターゲット操作のメッセージ アクションが指定されていることを確認します。 この例では、文字列の上に XmlReader を作成することで、メッセージ本文を渡します。 ターゲット操作は、SAP システムでSD_RFC_CUSTOMER_GET RFC を呼び出します。

    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. チャネルで Request メソッドを呼び出して、SAP アダプターにメッセージを送信し、応答を受信します。 SAP システムで例外が発生した場合、アダプターは TargetSystemException をスローします。 (SAP 以外の例外の場合は、その他の例外が発生する可能性があります)。SAP エラーの説明は、TargetSystemException の InnerException.Message プロパティから取得できます。

    try  
    {  
        Message messageOut = channel.Request(messageIn);  
    }  
    catch (Exception ex)  
    {  
        // handle exception  
    }  
    
  7. 応答を処理します。 この例では、応答メッセージで GetReaderAtBodyContents が呼び出され、メッセージ本文が取得されます。

    XmlReader readerOut = messageOut.GetReaderAtBodyContents();  
    
  8. 応答メッセージの処理が完了したら、リーダーとメッセージを閉じます。

    readerOut.Close();  
    messageOut.Close();  
    
  9. チャネルとチャネル ファクトリの使用が完了したら、それらを閉じます。 ファクトリを閉じると、そのファクトリで作成されたすべてのチャネルが閉じられます。

    channel.Close()  
    factory.Close();  
    
  10. 次を除き、 IOutputChannel 図形を使用してメッセージを送信するには、同じ手順に従います。

  • 手順 1 で ChannelFactory<IOutputChannel を> 作成します。

  • 手順 6 でチャネルで Send メソッドを呼び出します。 channel.Send(messageIn);.

  • IOutputChannel に対して返される応答メッセージはありません。

次の例は、 IRequestChannel チャネルを使用して RFC を呼び出す方法を示しています。 この例では、SD_RFC_CUSTOMER_GET RFC を呼び出して、名前が "AB" で始まる顧客の一覧を取得します。 応答メッセージは XmlReader を使用して使用され、返された各顧客の顧客番号と名前がコンソールに書き込まれます。

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

参照

WCF チャネル モデルを使用してアプリケーションを開発する