使用 WCF 服务模型将 IDOC 发送到 SAP

在内部,适用于 mySAP Business Suite 的 Microsoft BizTalk 适配器通过调用以下两个 RFC 之一将 IDOC 发送到 SAP 系统:

  • 版本 3 IDOC 的IDOC_INBOUND_ASYNCHRONOUS。

  • 版本 2 IDOC 的INBOUND_IDOC_PROCESS。

    可以通过调用相应的 RFC (或 tRFC) 将 IDOC 发送到适配器;但是,还可以使用以下两个操作将 IDOC 发送到适配器:

  • SendIdoc 直接显示在 IDOC 根节点下。 SendIdoc 操作将 IDOC 作为字符串 (弱类型) 数据发送到 SAP 适配器。

  • 发送 是针对每个 IDOC 单独显示。 发送操作将 IDOC 作为强类型数据发送到 SAP 适配器。

    这些操作确定如何将 IDOC 数据发送到适配器,而不是发送到 SAP 系统的方式。 适配器始终使用相应的 tRFC 将 IDOC 发送到 SAP 系统。

    由于 SAP 适配器将 IDOC 作为 tRFC 发送,因此 Send 和 SendIdoc 操作都公开了用于确认 (提交) IDOC 的 GUID 参数。 SAP 适配器在内部映射此 GUID 与与 tRFC 关联的 SAP 事务 ID (TID) 。 可以通过以下两种方式之一确认 IDOC:

  • 使用 AutoConfirmSentIdocs 绑定属性。 如果此绑定属性设置为 true,适配器会自动确认用于发送 IDOC 的 tRFC。

  • 通过调用 RfcConfirmTransID。 使用与 IDOC 关联的 GUID 调用此操作。

    以下部分介绍如何使用 SendIdoc 和 Send 操作将 IDOC 发送到 SAP 系统。 有关帮助将 IDOC 作为 tRFC 发送的详细信息,请参阅 使用 WCF 服务模型在 SAP 中调用 TFC

WCF 客户端类

SendIdoc 操作

SAP 适配器显示单个操作 (和服务协定) 以字符串格式发送 IDOC。 服务协定的名称为“Idoc”,WCF 客户端类为 IdocClient

可以使用此客户端将任何 IDOC 发送到 SAP。 它包含一个方法 SendIdoc,该方法采用两个参数:

  • idocData 是包含 IDOC 数据的字符串

  • guid 是映射到 SAP TID 的 GUID。

    以下代码显示了为 SendIdoc 操作生成的 WCF 客户端。

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
public partial class IdocClient : System.ServiceModel.ClientBase<Idoc>, Idoc {  
  
    public void SendIdoc(string idocData, ref System.Nullable\<System.Guid\> guid) {…}  
}  

发送操作

由于发送操作使用强类型数据,因此 SAP 适配器为每个 IDOC 显示唯一的服务协定。 为此协定生成的接口 (和 WCF 客户端类的名称) 基于 IDOC 类型、版本、版本号和 CIM 类型 ((如果相关) )。 例如,对于 ORDERS03.v3.620 IDOC,接口名为“IdocORDERS03V3R620”,WCF 客户端类为 IdocORDERS03V3R620Client

必须为每个不同类型的 IDOC 生成唯一的客户端。 此客户端包含一个方法 Send,该方法采用两个参数:

  • idocData 是表示强类型 IDOC 数据的类。

  • guid 是映射到 SAP TID 的 GUID 的字符串表示形式。

    以下代码显示了为 ORDERS03.v3.620 IDOC 显示的发送操作生成的 WCF 客户端。

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
public partial class IdocORDERS03V3R620Client : System.ServiceModel.ClientBase<IdocORDERS03V3R620>, IdocORDERS03V3R620 {  
  
    ...  
  
    public void Send(ORDERS03 idocData, ref string guid) { ... }  
}  

如何创建应用程序以发送 IDOC

若要将 IDOC 发送到 SAP 系统,请执行以下步骤。

将 IDOC 发送到 SAP 系统

  1. 生成 WCF 客户端类。 使用“添加适配器服务参考”Visual Studio 插件或 ServiceModel 元数据实用工具 (svcutil.exe) 生成面向要使用的 IDOC 的 WCF 客户端类。 有关如何生成 WCF 客户端的详细信息,请参阅 为 SAP 解决方案项目生成 WCF 客户端或 WCF 服务协定。 如果要显式确认 IDOC,请确保为 RfcConfirmTransID 操作生成 WCF 客户端。 可以在以下节点下找到操作:

    • SendIdoc 操作。 直接在 IDOC 节点下。

    • 发送操作。 在对应于目标 IDOC 的类型、版本和版本号的节点下。

    • RfcConfirmTransID 操作。 直接在 TRFC 节点下。

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

    SAPBinding binding = new SAPBinding();  
    
    // Set endpoint address  
    EndpointAddress endpointAddress = new EndpointAddress("sap://CLIENT=800;LANG=EN;@a/YourSAPHost/00?RfcSdkTrace=False&AbapDebug=False&UseSapGui=Without");  
    
    // Create client and set credentials  
    idocClient = new IdocClient(binding, endpointAddress);  
    idocClient.ClientCredentials.UserName.UserName = "YourUserName";  
    idocClient.ClientCredentials.UserName.Password = "YourPassword";;  
    
  3. 如果希望适配器在发送 IDOC 后确认 SAP 系统上的 tRFC,请将 AutoConfirmSentIdocs 绑定属性设置为 true。 在打开 WCF 客户端之前,必须执行此操作。

    // Set AutoConfirmSentIdocs property to true  
    binding.AutoConfirmSentIdocs = true;  
    
  4. 打开 WCF 客户端。

    idocClient.Open();  
    
  5. 在步骤 2 中创建的 WCF 客户端上调用相应的方法,将 IDOC 发送到 SAP 系统。 可以传递包含 GUID 或 guid 参数设置为 null 的变量。 如果未指定 GUID,SAP 适配器会为操作生成一个, (guidref 参数) 。 以下代码从文件中读取字符串格式) IDOC (,并使用 SendIdoc 操作将其发送到 SAP 系统。

    // Read IDOC into string variable  
    using (StreamReader reader = new StreamReader("ORDERS03.txt"))  
    {  
    idocData = reader.ReadToEnd();  
    }  
    
    //Get a new GUID to pass to SendIdoc. You can also assign a null  
    //value to have the adapter generate a GUID.  
    adapterTxGuid = Guid.NewGuid();  
    
    //Invoke SendIdoc on the client to send the IDOC to the SAP system  
    idocClient.SendIdoc(idocData, ref adapterTxGuid);  
    
  6. 如果未在步骤 3) 中将 AutoConfirmSentIdocs 绑定属性设置为 true (,则必须在 SAP 系统上确认 tRFC。 为此,必须在 TrfcClient (创建未显示) 上调用 RfcConfirmTransID 方法。 指定在步骤 4 中为 参数返回的 GUID。

    trfcClient.RfcConfirmTransID(adapterTxGuid);  
    
  7. 关闭 WCF 客户端 (和 TrfcClient(如果使用完) ,请在完成发送 IDOCs) 后 (关闭它。

    idocClient.Close();   
    

示例

以下示例使用 SendIdoc 方法将 IDOC 发送到 SAP 系统。 从文件中读取 IDOC,ORDERS03.txt。 此文件包含ORDERS03。V3.620 IDOC 和 包含在示例中;但是,SendIdoc 操作可用于发送任何 IDOC。

using System;  
using System.Collections.Generic;  
using System.Text;  
  
using System.IO;  
  
// Add WCF, 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;  
  
// This example sends a flat IDOC to the SAP system by using the SendIdoc operation.  
namespace SapIdocStringClientSM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            // variable for the IDOC client  
            IdocClient idocClient = null;  
  
            Console.WriteLine("IDOC string client sample started");  
            try  
            {  
                // Variable for the GUID  
                System.Nullable<System.Guid> adapterTxGuid;  
                // string to hold the Idoc data  
                string idocData;  
                // string to hold the SAP transaction ID (TID)  
                string sapTxId;  
  
                // The client can be configured from app.config, but it is   
                // explicitly configured here for demonstration.  
                // set AutoConfirmSentIdocs property to true  
                SAPBinding binding = new SAPBinding();  
                binding.AutoConfirmSentIdocs = true;  
  
                // Set endpoint address  
                EndpointAddress endpointAddress = new EndpointAddress("sap://CLIENT=800;LANG=EN;@a/YourSAPServer/00?RfcSdkTrace=False&AbapDebug=False&UseSapGui=Without");  
  
                // Create client and set credentials  
                idocClient = new IdocClient(binding, endpointAddress);  
                idocClient.ClientCredentials.UserName.UserName = "YourUserName";  
                idocClient.ClientCredentials.UserName.Password = "YourPassword";  
  
                // Open the client and send the Idoc  
                idocClient.Open();  
  
                // Read IDOC into string variable  
                using (StreamReader reader = new StreamReader("ORDERS03.txt"))  
                {  
                    idocData = reader.ReadToEnd();  
                }  
  
                //Get a new GUID to pass to SendIdoc. You can also assign a null.  
                //value to have the adapter generate a GUID.  
                adapterTxGuid = Guid.NewGuid();  
  
                //Invoke SendIdoc on the client to send the IDOC to the SAP system.  
                idocClient.SendIdoc(idocData, ref adapterTxGuid);  
  
                // The AutoConfirmSentIdocs binding property is set to true, so there is no need to  
                // confirm the IDOC. If this property is not set to true, you must call the   
                // RfcConfirmTransID method of a TrfcClient with adapterTxGuid to   
                // confirm the transaction on the SAP system.   
  
                // Get SAP tx id from GUID  
                sapTxId = SAPAdapterUtilities.ConvertGuidToTid((Guid) adapterTxGuid);  
  
                Console.WriteLine("IDOC sent");  
                Console.WriteLine("The SAP Transaction Id is : " + sapTxId);  
  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                }  
            }  
            finally  
            {  
                // Close the IDOC client  
                if (idocClient != null)  
                {  
                    if (idocClient.State == CommunicationState.Opened)  
                        idocClient.Close();  
                    else  
                        idocClient.Abort();  
                }  
            }  
  
        }  
    }  
}  

另请参阅

使用 WCF 服务模型开发应用程序