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

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

  • SAP 适配器将 tRFC 显示在不同于 RFC 的节点(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”下。 这意味着,一个单一的 WCF 客户端类 TrfcClient 被创建用于您想调用的所有 tRFC 操作。 每个目标 tRFC 都表示为此类的方法。 对于每个方法:

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

    以下代码显示了 TrfcClient 类的一部分,以及在 SAP 系统上作为 tRFC 调用 BAPI_SALESORDER_CREATEFROMDAT2 的方法。 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 客户端应用程序

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

  • 必须在 TRFC 节点下检索这些目标操作。

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

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

创建 tRFC 客户端应用程序

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

  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 的变量,或包含空 GUID 的 TransactionalRrcOperationIdentifier 参数的变量。 如果传递空的 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。

    trfcClient.Close();   
    

示例:

以下示例演示如何将BAPI_SALESORDER_CREATE作为 tRFC 调用。

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 中对 tRFCs 的操作