事务远程函数调用(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 客户端应用程序
生成 TrfcClient 类。 使用“添加适配器服务引用 Visual Studio 插件”或 ServiceModel 元数据实用工具(svcutil.exe)生成一个 TrfcClient 类,以针对您要使用的 RFC。 有关如何生成 WCF 客户端的详细信息,请参阅 为 SAP 解决方案项目生成 WCF 客户端或 WCF 服务协定。 确保将 RfcConfirmTransID 操作包含在 TrfcClient 类中。
创建步骤 1 中生成的 TrfcClient 类的实例并指定客户端绑定。 指定客户端绑定涉及指定 TrfcClient 将使用的绑定和终结点地址。 可以在代码中强制执行此作,也可以在配置中以声明方式执行此作。 有关如何指定客户端绑定的详细信息,请参阅 为 SAP 系统配置客户端绑定。 以下代码通过配置初始化 TrfcClient,并为 SAP 系统设置凭据。
TrfcClient trfcClient = new TrfcClient("SAPBinding_Rfc"); trfcClient.ClientCredentials.UserName.UserName = "YourUserName"; trfcClient.ClientCredentials.UserName.Password = "YourPassword";
打开 TrfcClient。
trfcClient.Open();
在步骤 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);
若要确认与 SAP 系统上的 tRFC 关联的 TID,请调用 TrfcClient 上的 RfcConfirmTransID 方法。 为 TransactionRfcOperationIdentifier参数指定步骤 4 中返回的 GUID。
trfcClient.RfcConfirmTransID(transactionalRfcOperationIdentifier);
使用 完 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();
}
}
}
}
}