使用 WCF 服务模型在 SAP 中调用 tRFC

事务性远程函数调用 (tRFC) 保证在 SAP 系统上 一次性 执行 RFC。 可以将 SAP 适配器显示的任何 RFC 作为 tRFC 调用。 在 WCF 服务模型中调用 tRFC 类似于调用 RFC,但存在以下差异:

  • SAP 适配器在与 RFC (RFC) 不同的节点 (TRFC) 下显示 tRFC。

  • tRFC 客户端调用不返回 SAP 导出和更改参数的值。

  • tRFC 操作包括一个 GUID 参数,该参数由 SAP 适配器映射到 tRFC 的 SAP 事务 ID (TID) 。

  • 调用 tRFC 后,必须调用 RfcConfirmTransID 操作以确认 (提交) SAP 系统上的 tRFC。 此操作直接显示在 TRFC 节点下。

    有关 tRFC 操作和 RfcConfirmTransID 操作的详细信息,请参阅 SAP 中 tRFC 的操作

    以下部分演示如何使用 SAP 适配器在 SAP 系统上调用 tRFC。

WCF 客户端类

SAP 适配器显示单个服务协定“Trfc”下的所有 tRFC 操作。 这意味着为要调用的所有 tRFC 操作创建单个 WCF 客户端类 TrfcClient。 每个目标 tRFC 表示为此类的方法。 对于每个方法:

  • 复杂的 SAP 类型(如结构)显示为 .NET 类,其属性对应于 SAP 类型的字段。 这些类在以下命名空间中定义: microsoft.lobservices.sap._2007._03.Types.Rfc

    以下代码演示 了 TrfcClient 类的一部分,以及调用 BAPI_SALESORDER_CREATEFROMDAT2 (作为 SAP 系统上的 tRFC) 的方法。 TransactionalRfcOperationIdentifier 参数包含映射到 SAP TID 的 GUID。 不会显示方法的所有参数。

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
public partial class TrfcClient : System.ServiceModel.ClientBase<Trfc>, Trfc {  
  
    ....  
  
    /// <summary>The Metadata for this RFC was generated using the RFC SDK.</summary>  
    public void BAPI_SALESORDER_CREATEFROMDAT2(  
                string BEHAVE_WHEN_ERROR,   
                string BINARY_RELATIONSHIPTYPE,   
                string CONVERT,   
                string INT_NUMBER_ASSIGNMENT,   
                microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISDLS LOGIC_SWITCH,   
                microsoft.lobservices.sap._2007._03.Types.Rfc.BAPISDHD1 ORDER_HEADER_IN,   
  
                …  
  
               microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIADDR1[] PARTNERADDRESSES,   
                microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIRET2[] RETURN,   
                ref System.Guid TransactionalRfcOperationIdentifier) { ...  }  
}  

以下代码显示了为 RfcConfirmTransID 操作生成的 方法。 必须确保此方法作为 TrfcClient 的一部分生成。 RfcConfirmTransID 操作直接显示在 TRFC 节点下。

public void RfcConfirmTransID(System.Guid TransactionalRfcOperationIdentifier) {…}  

如何创建 tRFC 客户端应用程序

创建调用 TFC 的应用程序的步骤类似于调用 RFC 的步骤,但以下例外:

  • 必须检索 TRFC 节点下的目标操作。

  • 必须检索 RfcConfirmTransID 操作。 这直接显示在 TRFC 节点下。

  • 若要确认 (提交) SAP 系统上的 tRFC 操作,必须使用为该 tRFC 操作返回的 GUID 调用 RfcConfirmTransID 操作。

创建 tRFC 客户端应用程序

  1. 生成 TrfcClient 类。 使用添加适配器服务引用 Visual Studio 插件或 ServiceModel 元数据实用工具 (svcutil.exe) 生成一个面向要使用的 RFC 的 TrfcClient 类。 有关如何生成 WCF 客户端的详细信息,请参阅 为 SAP 解决方案项目生成 WCF 客户端或 WCF 服务协定。 确保 TrfcClient 类中包含 RfcConfirmTransID 操作。

  2. 创建步骤 1 中生成的 TrfcClient 类的实例,并指定客户端绑定。 指定客户端绑定涉及指定 TrfcClient 将使用的绑定和终结点地址。 可以在代码中强制执行此操作,也可以在配置中以声明方式执行此操作。 有关如何指定客户端绑定的详细信息,请参阅 为 SAP 系统配置客户端绑定。 以下代码从配置初始化 TrfcClient 并设置 SAP 系统的凭据。

    TrfcClient trfcClient = new TrfcClient("SAPBinding_Rfc");  
    
    trfcClient.ClientCredentials.UserName.UserName = "YourUserName";  
    trfcClient.ClientCredentials.UserName.Password = "YourPassword";  
    
  3. 打开 TrfcClient

    trfcClient.Open();  
    
  4. 在步骤 2 中创建的 TrfcClient 上调用适当的方法,以调用 SAP 系统上的目标 tRFC。 可以传递一个变量,该变量包含 GUID 或包含 事务性RrcOperationIdentifier 参数的空 GUID。 如果传递一个空的 GUID,SAP 适配器将为你生成一个。 以下代码在 SAP 系统上调用BAPI_SALESORDER_CREATEFROMDAT2作为 tRFC, (方法的所有参数都) 显示。 指定了 GUID。

    transactionalRfcOperationIdentifier = Guid.NewGuid();  
    
    //invoke RFC_CUSTOMER_GET as a tRFC  
    trfcClient.BAPI_SALESORDER_CREATEFROMDAT2(  
                                    request.BEHAVE_WHEN_ERROR,  
                                    request.BINARY_RELATIONSHIPTYPE,  
                                    request.CONVERT,  
    
                                    ...  
    
                                    ref transactionalRfcOperationIdentifier);  
    
  5. 若要确认与 SAP 系统上的 tRFC 关联的 TID,请在 TrfcClient 上调用 RfcConfirmTransID 方法。 为 TransactionRfcOperationIdentifier参数指定步骤 4 中返回的 GUID。

    trfcClient.RfcConfirmTransID(transactionalRfcOperationIdentifier);  
    
  6. 使用完 TrfcClient 后, (完成调用所有 tRFC) 后将其关闭。

    trfcClient.Close();   
    

示例

以下示例演示如何以 tRFC 的形式调用BAPI_SALESORDER_CREATE。

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add WCF, the 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;  
  
using microsoft.lobservices.sap._2007._03.Types.Rfc;  
  
// This example demonstrates sending BAPI_SALESORDER_CREATEFROMDAT2 as a tRFC. The client has   
// methods to:  
//      send the BAPI (BAPI_SALESORDER_CREATEFROMDAT2)and to  
//      Confirm the transaction (RfcConfirmTransID)  
// An instance of BAPI_SALESORDER_CREATEFROMDAT2Request (generated)   
// is used to format the BAPI before invoking BAPI_SALESORDER_CREATEFROMDAT2. This   
// is not necessary, but is done to make it easier to read the code.  
// tRFC invocations always includes a ref parameter that contains a GUID. You can optionally   
// set this parameter when you invoke the method; however, you must use the value returned by  
// the adapter when you call RfcConfirmTransID to confirm the transaction on the SAP system.   
// You can call the utility method, SAPAdapterUtilities.ConvertGuidToTid, to get the value  
// of the SAP transaction Id from the GUID that the adapter returns.  
namespace SapTrfcClientSM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            TrfcClient sapTrfcClient = null;  
  
            try  
            {  
                Console.WriteLine("SAP TRFC client sample started");  
                Console.WriteLine("Creating the TRFC client");  
                // Create the SAP Trfc Client from configuration  
                sapTrfcClient = new TrfcClient("SAPBinding_Trfc");  
                sapTrfcClient.ClientCredentials.UserName.UserName = "YourUserName";  
                sapTrfcClient.ClientCredentials.UserName.Password = "YourPassword";  
  
                Console.WriteLine("Opening the TRFC client");  
                // Open the Trfc Client  
                sapTrfcClient.Open();  
  
                // Create a GUID -- note: this is optional. If you do not pass a GUID,  
                // for the TransactionalRfcOperationIdentifier parameter, the SAP adapter will   
                // generate one, associate it with the SAP TID, and set the   
                // TransactionalRfcOperationIdentifier parameter.  
                Guid tidGuid = Guid.NewGuid();  
  
                BAPI_SALESORDER_CREATEFROMDAT2Request request = new BAPI_SALESORDER_CREATEFROMDAT2Request();  
  
                request.ORDER_HEADER_IN = new BAPISDHD1();  
                request.ORDER_HEADER_IN.DOC_TYPE = "TA";  
                request.ORDER_HEADER_IN.SALES_ORG = "1000";  
                request.ORDER_HEADER_IN.DISTR_CHAN = "10";  
                request.ORDER_HEADER_IN.DIVISION = "00";  
                request.ORDER_HEADER_IN.SALES_OFF = "1000";  
                request.ORDER_HEADER_IN.REQ_DATE_H = DateTime.Now;  
                request.ORDER_HEADER_IN.PURCH_DATE = DateTime.Now;  
                request.ORDER_HEADER_IN.PURCH_NO_C = "Cust PO";  
                request.ORDER_HEADER_IN.CURRENCY = "EUR";  
  
                BAPISDITM[] orderItems = new BAPISDITM[1];  
                orderItems[0] = new BAPISDITM();  
                orderItems[0].MATERIAL = "P-109";  
                orderItems[0].PLANT = "1000";  
                orderItems[0].TARGET_QU = "ST";  
                request.ORDER_ITEMS_IN = orderItems;  
  
                BAPIPARNR[] orderPartners = new BAPIPARNR[1];  
                orderPartners[0] = new microsoft.lobservices.sap._2007._03.Types.Rfc.BAPIPARNR();  
                orderPartners[0].PARTN_ROLE = "AG";  
                orderPartners[0].PARTN_NUMB = "0000001390";  
                request.ORDER_PARTNERS = orderPartners;  
  
                // Create a GUID -- note: this is optional. If you do not pass a GUID,  
                // for the TransactionalRfcOperationIdentifier parameter, the SAP adapter will   
                // generate one, associate it with the SAP TID, and set the   
                // TransactionalRfcOperationIdentifier parameter.  
                request.TransactionalRfcOperationIdentifier = Guid.NewGuid();  
  
                Console.WriteLine("Invoking BAPI_SALESORDER_CREATEFROMDAT2 as a tRFC");  
  
                //invoke RFC_CUSTOMER_GET as a tRFC  
                sapTrfcClient.BAPI_SALESORDER_CREATEFROMDAT2(request.BEHAVE_WHEN_ERROR,  
                                                                request.BINARY_RELATIONSHIPTYPE,  
                                                                request.CONVERT,  
                                                                request.INT_NUMBER_ASSIGNMENT,  
                                                                request.LOGIC_SWITCH,  
                                                                request.ORDER_HEADER_IN,  
                                                                request.ORDER_HEADER_INX,  
                                                                request.SALESDOCUMENTIN,  
                                                                request.SENDER,  
                                                                request.TESTRUN,  
                                                                request.EXTENSIONIN,  
                                                                request.ORDER_CCARD,  
                                                                request.ORDER_CFGS_BLOB,  
                                                                request.ORDER_CFGS_INST,  
                                                                request.ORDER_CFGS_PART_OF,  
                                                                request.ORDER_CFGS_REF,  
                                                                request.ORDER_CFGS_REFINST,  
                                                                request.ORDER_CFGS_VALUE,  
                                                                request.ORDER_CFGS_VK,  
                                                                request.ORDER_CONDITIONS_IN,  
                                                                request.ORDER_CONDITIONS_INX,  
                                                                request.ORDER_ITEMS_IN,  
                                                                request.ORDER_ITEMS_INX,  
                                                                request.ORDER_KEYS,  
                                                                request.ORDER_PARTNERS,  
                                                                request.ORDER_SCHEDULES_IN,  
                                                                request.ORDER_SCHEDULES_INX,  
                                                                request.ORDER_TEXT,  
                                                                request.PARTNERADDRESSES,  
                                                                request.RETURN,  
                                                                ref request.TransactionalRfcOperationIdentifier);  
  
                string sapTxId = null;  
                sapTxId = SAPAdapterUtilities.ConvertGuidToTid(request.TransactionalRfcOperationIdentifier);  
  
                Console.WriteLine("BAPI_SALESORDER_CREATEFROMDAT2 Sent");  
                Console.WriteLine("The SAP Transaction Id is " + sapTxId);  
  
                // Invoke the RfcConfirmTransID method to confirm (commit) the transaction on  
                // the SAP system. This step is required to complete the transaction. The SAP  
                // adapter will always return a TranactionalRfcOperationIdentifier, whether   
                // one was supplied in the call or not.  
                sapTrfcClient.RfcConfirmTransID(request.TransactionalRfcOperationIdentifier);  
  
                Console.WriteLine("SAP Transaction {0} has been committed", sapTxId);  
  
                Console.WriteLine("\nHit <RETURN> to end");  
                Console.ReadLine();  
  
            }  
            catch (ConnectionException cex)  
            {  
                Console.WriteLine("Exception occurred connecting to the SAP system");  
                Console.WriteLine(cex.InnerException.Message);  
                throw;  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                }  
                throw;  
            }  
            finally  
            {  
                // Close the client  
                if (sapTrfcClient != null)  
                {  
                    if (sapTrfcClient.State == CommunicationState.Opened)  
                        sapTrfcClient.Close();  
                    else  
                        sapTrfcClient.Abort();  
                }  
            }  
  
        }  
    }  
}  

另请参阅

使用 WCF 服务模型开发应用程序
SAP 中 TRFC 的操作