Skip to Content

The SAP ALE/IDoc technology is one important SAP integration technology for asynchronous messaging between SAP systems / external systems.  Sometimes you need to develop an external IDoc receiver program to “subscribe” to IDocs sent by the SAP system.  There are several connectors that you can use, among them the SAP .NET Connector (DNC), which provides some basic support for you to develop such an IDoc receiver program.

After installing DNC, in your IDoc receiver project, you need to add references to SAP.Connector and SAP.Connector.Rfc .

SAP DNC provides a SAP.Connector.SAPIDocReceiver base class that you must derive from to create your own IDoc receiver class.

Receiving event handlers

SAPIDocReceiver has BeginReceive and EndReceive events to which you register your receiving event handlers through the SAPIDocReceiver.ReceiveEventHandler delegate.  In the BeginReceive handler method you can, e.g., attach the IDOC stream to a writer of some sort.  In the EndReceive handler method you can then work with the data received.  The following code segment illustrates this:

// This method is called when an IDoc is received.  We tell the IDoc receiver to write to a stream writer.

private void idoc_BeginReceive(object sender, SAP.Connector.SAPIDocReceiver.ReceiveEventArgs e) {

            Console.WriteLine(“IDoc begin receive”);

            sw = new System.IO.StreamWriter(@”C:\temp\idocs.txt”, true, System.Text.Encoding.ASCII);

            e.WriteTo = sw;

}

// This method is called when IDoc receiving is done.  We can close the stream writer now.

private void idoc_EndReceive(object sender, SAP.Connector.SAPIDocReceiver.ReceiveEventArgs e) {

            Console.WriteLine(“IDoc end receive”);

            sw.Close();

}

// Register event handlers.  idocreceiver is an instance of the class derived from SAPIDocReceiver

idocreceiver.BeginReceive += new SAP.Connector.SAPIDocReceiver.ReceiveEventHandler(this.idoc_BeginReceive);

idocreceiver.EndReceive += new SAP.Connector.SAPIDocReceiver.ReceiveEventHandler(this.idoc_EndReceive);

tRFC handling methods

IDocs are transmitted using the tRFC protocol, which is designed to guarantee that an IDoc is transmitted to and processed by the receiver once and only once.  Here is a brief explanation of how tRFC works when SAP system sends out an IDoc:

– SAP system generates a globally unique Transaction ID (TID) for each IDoc transmission, and passes the TID along with the IDoc data.  When the IDoc receiver receives the tRFC call, it must first checks the TID against its own log of TIDs that have already been processed. 

– If the TID is new, the IDoc receiver should logs the TID and processes the IDoc.  Once the IDoc is successfully processed by the receiver, SAP system makes a TID confirmation call asking the receiver to set the TID state to “confirmed”.

– If the TID has already been previously processed, the IDoc receiver must skip the processing.

– If the SAP system detects an error, e.g., loss of the connection to the IDoc receiver, during the IDoc transmission, the SAP system will automatically schedule a retry of the IDoc transmission with the same TID at a later time.

In your derived class you need to implement the following four tRFC handling functions:

 protected override System.Int32 CheckTransaction(SAP.Connector.RfcTID tid)

  This is the first method called when DNC runtime receives an incoming IDoc transmission.  The method should check if this tid has already been processed.  If this tid is new, save it, return 0; the IDoc will be processed by your receiving handler methods normally.  If this tid has already been processed, return 1.  In case of other error, return -1. 

 protected override System.Int32 CommitTransaction(SAP.Connector.RfcTID tid)

This method is called if there is no problem during the receiving of the IDoc.  You should commit the changes made by CheckTransaction() and your receiving handler methods. 

protected override void RollbackTransaction(SAP.Connector.RfcTID tid)

This method is called if there is a problem during the receiving of the IDoc, e.g., when the receiving handler methods throw an Exception.  You should rollback the changes made by the CheckTransaction() and your receiving handler methods. 

 protected override System.Int32 ConfirmTransaction(SAP.Connector.RfcTID tid)

This method is called after a successful IDoc transmission.  You should either change the TID state to “confirmed”, or remove the tid from your TID store to save space.

Creating multiple IDoc receiver threads

DNC has made creating multiple IDoc receiver threads very easy.  You can use an instance of SAP.Connector.SAPServerHost as a container to host one or more IDoc receiver instances.  The following code segment illustrates this;

private SAPServerHost idochost = new SAPServerHost();

// create three identical IDoc receivers

int noOfServers = 3;

MyIDocReceiver idocreceiver = null;

if (idochost.Components.Count == 0) {

  for (int i=0;i<noOfServers; i++)

  {   

      idocreceiver = new MyIDocReceiver(args, idochost);  // args containing the SAP system conection parameters

      Console.WriteLine(“Created IDoc receiver {0}”, i+1);               

  }

}

// start all the IDoc receivers in the host

Console.WriteLine(“\n . . . starting all IDoc receivers in the IDoc Server host . . .”);

idochost.Start();

How many IDoc receiver instances you should create depends on the IDoc transmission volume etc. of your environment.

Making the IDoc server robust

To make the IDoc server robust, e.g., to be able to recover from temporary network connection problem or the restarting of the SAP system, you need to derive your own class from SAPServerHost .  In your derived class, you need to override the exception handler

  public override ActionOnServerException OnServerException ( SAP.Connector.SAPServer server , System.Exception e )

This method is called whenever a hosted IDoc receiver instance, which is an instance of SAP.Connector.SAPServer, throws an exception.  

The default handler returns ActionOnServerException.Terminate , which will cause the IDoc receiver instance stop to run.  What you should do in your handler depends on the particularity of your projects.  Generally, you may want to:

– Examine the current status of the IDoc receiver instance, by comparing the ServerHostStatus value with the various constants defined in the SAPServerStatus enum.

– Delay (sleep) for a while if necessary.  The delay value can start small and incrementally increase till a maximum.

– Then try to reconnect by returning ActionOnServerException.Reconnect .  Please note that ActionOnServerException.AutoReconnect is not implemented in the current DNC version (up to 2.0) so you can practically forget about it.

Parsing the received IDoc data stream?

Currently DNC does not provide any help to parse the received IDoc data stream.  In the future – nobody knows when – DNC may provide functionality to help you to parse an Idoc.  For now, however, you are on you own in this.

You can find data structure information of an IDoc type in SAP Interface Repository , or use the WE60 transaction in your SAP system.

To report this post you need to login first.

3 Comments

You must be Logged on to comment or reply to a post.

  1. Peter Van Kerkhove
    Hello,

    I’m using the .net connector 2.0 to receive IDOCs within my .NET client application.
    Whenever I run the CSServerIdocReceiver sample application (provided with the SAP .NET connector), I manage to receive IDOCs. However, if I’m sending additional IDOCs after waiting approximately 2 minutes, the client application DOES NOT RECEIVE anything anymore. I added the ActionOnServerException.Reconnect withen the override (as you mentioned in your blog), but this doesn’t help (no exception is perceived within the SAP .net connector client.) It looks like the registration of the external application within SAP has timed-out??  Has someone experience an alike problem?

    Best regards,
    Peter Van Kerkhove
    CODit 

    (0) 
    1. Dear Peter,
      This kind of question is best to be posted on the SDN Forum, or report directly to SAP support.
      Thank you for your understanding!
      Best regards,
      Robert
      (0) 
  2. Geert Steyaert
    Hi Robert, I have a few questions on this …
    – I can see the DNC doesn’t have any functionality to parse the file quickly. But what about .NET itself. One can use an XML file port in SAP instead of the fixed width flat file format. Is there no way, utilizing the XSD file for that specific IDOC type, to let .NET ‘magically’ de-serialize the filestream into an object ?

    – second, presume you need to further transmit the resulting object (de-serialized) to a webservice. In .NET Visual Studio I generated the WS proxy based on the WSDL file I got from ‘the other side’. They used for there Web Service also the same SAP supplied XSD file.  How go about that ?

    In fact I’m trying to transmit an DEBMAS06 to a external, non-Sap WebService but I’m on WAS 6.20 release so I don’t have easy ABAP WS consumer support. And I’m using a (working) intermediate DNC SapIdocReceiver service but I don’t want to program all the manual parsing steps/tree …

    Thanks for all your toughts,

    Geert

    (0) 

Leave a Reply