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

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

  • SAP 适配器将 TRFC 与 RFC (RFC) 节点 (TFC) 。

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

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

  • 调用 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 客户端应用程序

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

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

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

  • 若要 (在 SAP) 提交 tRFC 操作,必须使用针对该 tRFC 操作返回的 GUID 调用 RfcConfirmTransID 操作。

创建 tRFC 客户端应用程序

  1. 生成 TrfcClient 类。 使用"添加适配器服务Visual Studio插件或 ServiceModel 元数据实用工具工具 (svcutil.exe) 生成面向要使用的 RFC 的 TrfcClient 类。 若要详细了解如何生成 WCF 客户端,请参阅为 SAP 解决方案生成 WCF 客户端或 WCF 服务Artifacts。 确保 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 的变量或包含 TransactionalRrcOperationIdentifier 参数的空 GUID 的变量。 如果传递空 GUID,SAP 适配器会生成一个 GUID。 以下代码调用 BAPI_SALESORDER_CREATEFROMDAT2 作为 sap 系统上的 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 方法。 为 TransactionRfcOperationIdentifierparameter 指定步骤 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 上的操作