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

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

  • 用于版本 3 IDOC 的 IDOC_INBOUND_ASYNCHRONOUS。

  • INBOUND_IDOC_PROCESS用于版本2的IDOC。

    可以通过调用相应的 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 中调用 tRFC

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) { ... }  
}  

如何创建应用程序来发送 IDOCs

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

将 IDOC 发送到 SAP 系统

  1. 生成 WCF 客户端类。 使用“添加适配器服务引用 Visual Studio 插件”或 ServiceModel 元数据实用工具(svcutil.exe)生成针对您要处理的 IDOC 的 WCF 客户端类。 有关如何生成 WCF 客户端的详细信息,请参阅 生成适用于 SAP 解决方案项目的 WCF 客户端或 WCF 服务协定。 如果要显式确认 IDOCs,请确保为 "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 的变量,或者将变量设置为 null 以用于 guid 参数。 如果未指定 GUID,SAP 适配器会为作生成一个 GUID(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. 如果未将 AutoConfirmSentIdocs 绑定属性设置为 true (在步骤 3 中),则必须确认 SAP 系统上的 tRFC。 为此,必须在 TrfcClient 上调用 RfcConfirmTransID 方法(未显示创建)。 为参数指定步骤 4 中返回的 GUID。

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

    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 服务模型开发应用程序