Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Kudos

Introduction



Business APIs (BAPI) are defined in the Business Object Repository (BOR) as methods of SAP business object types or SAP interface types, and are implemented as function modules
in the ABAP code.
Each BAPI returns status information about its execution in a complex parameter named
Return in its output message.
This parameter reports exception messages or success messages back to the calling program.
BAPIs themselves must not trigger any messages (such as MESSAGE xnnn) in the
ABAP coding. In particular they must not generate terminations or display dialog boxes.
Instead, all messages must be intercepted internally and reported back to the calling program in the Return parameter.
If, in at least one of the entries of Return parameter, the field Type is filled with A (abort) or E (error), a database rollback is
executed in the standard programming model, that is, all tasks performed since the last COMMIT WORK are canceled.




In the past the only way to access a BAPI from .NET was to make RFC calls to the function modules on which the BAPI is based using the
+SAP
Connector for Microsoft .NET+ (NCo). However SAP NCo version 1.x and 2.x will not install inside
Visual Studio 2005. Instead developers have to build components in Visual Studio 2003 and use these in Visual Studio 2005 projects as described in the document

Using SAP Connector for MS .NET (NCO) in Microsoft Visual Studio 2005
.



As an alternative approach to RFC based communication made
available by the SAP connector for Microsoft .NET it is strongly recommended by
SAP to use Web Services as the de-facto standard for interoperability between
software (systems) of heterogeneous implementations. (see

SAP Note 943349
). SAP systems that are based on the SAP NetWeaver Application Server allow for a Web
service based communication since it is possible to create a Web service for every BAPI using the

Web Service Creation Wizard
.



If one of the error conditions mentioned above does occur when calling a BAPI one would like to throw an exception in
the calling .NET program.
If a BAPI is called using the SAP NCo the mechanism of throwing a BAPI specific .NET exception can be activated during design time.
The .NET proxy that is generated by the NCo then contains the .NET coding that performs this task. In contrast to a proxy generated by the NCo a Web service
proxy that is generated from a Web reference does not contain coding that throws
an exception.



In my blog I would therefore like to introduce a set of C#-classes that can be used to throw .NET exceptions in the calling .NET Web services client
thus allowing to have the same functionality of exception handling as it has
been available with the NCo.


"Checker" class SAP.NetWeaver.Bapi.BapiException.BapiRetCheck


Since the coding of the Web service proxy does not throw a .NET execption a new
checker class SAP.NetWeaver.Bapi.BapiException had to be implemented that
performs a check for the Return parameter in the calling .NET client. By just adding one line of code


checker.Check(bapiReturn);


an exception of type SAP.NetWeaver.BAPI.BapiException will be thrown if at least
in one of the entries of
the Return parameter (here: bapiReturn), the field Type is filled with A (abort) or E (error).



BAPI Return Parameter


The export parameter Return can be implemented in a BAPI in two different ways:



    1. As a structure, whereby it is defined in the function module as an export parameter.



     
     




 



    1. As a table, whereby it is defined in the function module as a table parameter


     
     



The Return parameter may thereby be based on one the following reference structures:






    1. BAPIRET2

    2. BAPIRET1

    3. BAPIRETURN

    4. BAPIRETURN1


While BAPIRET2 is used in new BAPIs the structures BAPIRET1, BAPIRETURN and BAPIRETURN1 may still partly
be used in old BAPIs. The structures BAPIRET1 and BAPIRETURN1 consist of the same fields as the BAPIRET2 structure excluding the fields PARAMETER, ROW, FIELD and SYSTEM. The structure BAPIRETURN consists of the same fields as BAPIRETURN1 and BAPIRET1 excluding the field NUMBER that is used to store the numeric value of the BAPI Return code. The BAPIRETURN structure therefore uses the field CODE instead.


Since the Return parameter may be based on one of the four mentioned reference structures and because it may be returned as a structure or a table a developer could be confronted with up to eight different options how a BAPI returns its Return code.
It was therefore one of the design goals to use a generic coding to check for the BAPI Return codes.


Reflection


The .NET Framework allows developers to
discover information about types included in their programs or in other
assemblies. This is referred to as Reflection and it is provided through a set
of .NET base classes included in the System.Reflection namespace. This
sample uses the System.Reflection namespace and some of the main classes
to gather information on the various types that may be used by a Return code
that is returned by the Web service proxy.</p>


How to use the Checker Class


Before digging into the coding of the checker class we first want to have a
look how it can be used. The coding that contains the class declarations resides in one code File BapiRet.cs
which can thus easily be added to any existing project.</p>


 Step 1: Add BapiException.cs to the project


          
  • In Solution Explorer, select a
    target project.

  • On the Project menu, select Add
    Existing Item.

In the Add Existing dialog box,
     locate and select the the file BapiException.cs that you want to add.</li>
     
               

 


               
</ol>

Step 2: Add using directive for the Namespace SAP.NetWeaver.Bapi


Add the following using directive to your coding:


using SAP.NetWeaver.Bapi;


Step 3: Create Checker object


Now we have to create an instance of the checker object. To do this we add
the following line to the coding where the other varaibles are declared.




     

// Create a checker object


BapiRetCheck checker = new BapiRetCheck();





Step 4:  Perform check


As shown in the coding of a C# Web services command line
application below we just have to add one single line of code after the call of the
Web service proxy.





If the Return parameter is defined as a structure the Web service call will look like

          

               


If the Return parameter is defined as a table the Web service call will look like

               


Step 5: Add exception handling


We now have to add the exception handling.for the BAPI Exceptions that might be
raised. It is recommended to have at least two catch blocks.
The first catch statement is for the SAP specific exceptions of type +
SAP.NetWeaver.Bapi.BapiException +and the second for others (generic),
for example errors from the runtime or other resources.


If the Return parameter does not contain an error message the content of
the Return parameter can also be retrieved using the property ReturnTable
of the checker object.



Example: C# Web services client commandline application


Sample Code


The sample code consists out of three classes that are using the namespace +
SAP.NetWeaver.Bapi+.  The class BapiRetCheck is used to check the
Return Parameter of a BAPI that is called via Web services. The class ReturnParameters
is used as a generic storage for the content that is retrieved from the Return
parameter. The class  BapiException  is derived from System.Exception.
If  in at least one of the entries of Return parameter, the field Type is filled with A (abort) or E (error)
an exception of type SAP.NetWeaver.Bapi.BapiException.</p>

Class BapiRetCheck


The method check takes the Return parameter as an argument. </span>The
Return parameter is passed as an object called bapiReturn. If the+
Return+ parameter in the BAPI is implemented as a table bapiReturn is
an array.


!https://weblogs.sdn.sap.com/weblogs/images/11352/bapiRet2Table.png|height=380|alt=image|width=600|sr...!


If the+ Return+ parameter in the BAPI is implemented as an export
parameter bapiReturn is a complex structure.</p>

As a first step it is checked whether the object bapiReturn is an array. If
the object bapiReturn is an array of objects a loop is performed to iterate
through all members. Check then passes the single object(s) to the private method +
PerformCheck+.


PerformCheck first checks whether bapiReturn has has either
the structure of BAPIRET2
, BAPIRET1 BAPIRETURN or BAPIRETURN1. If the check went OK the content of the
fields of the Return parameter are assigned to an ReturnParameters object
bapiReturnParameters.


Now +
PerformCheck+ checks whether the property +Type +of +bapiReturnParameters
+contains "A" or "E" which would raise an exception of type +BapiException.
+Otherwise the content is added as an additional item to the property ReturnTable..</p>

     

if ((bapiReturnParameters.Type == "E") || (bapiReturnParameters.Type ==
"A"))

    throw new BapiException(bapiReturnParameters); // in case if
real error otherwise just return

else

    this.ReturnTable.Add(bapiReturnParameters);


Class BapiException


The class BapiException is derived from System.Exception.
If this exception is raised it gets the the
entry of the Return parameter where the field Type filled with A (abort) or E (error)
as an argument. The argument is a ReturnParameters object that is used to store
the content of the different Bapi Return structures generically.

It is thus possible to retrieve the content of each field of the error message allowing for the development of an appropriate exception handler.





    catch (BapiException e)n e)

    {

        Console.WriteLine("BAPI Exception caught");

        Console.WriteLine("NUMBER: " + e.BapiReturn.Number);

        Console.WriteLine("Message: " + e.BapiReturn.Message);

    }   

 




It is recommended to have at least two catch blocks.
The first catch statement is then used for the SAP specific exceptions of type BapiException
while the second is used for others (generic) exceptions,
for example errors from the runtime or other resources.


Class ReturnParameters


The class ReturnParameters  is used to store
generically the content of the complex structures BAPIRET2, BAPIRET1, BAPIRETURN
and BAPIRETURN1.  It therefore has properties for each field that can be
returned by on of the four structures. The property ReturnTable is used
by +BapiRet +objects to hold a list of objects based on ReturnParameters.








































PropertyTypeDescriptionBAPIRET2BAPIRET1BAPIRETURNBAPIRETURN1
TYPEstringMessage type:

    1. S (Success) for success messages

    2. E (Error) for erroneous situations

    3. W (Warning) for warnings

    4. I (Info) for information messages

    5. A (Abort) for abort messages

XXXX
IDstringMessage, message classXX X
CODEstringMessage, message code  X 
NUMBERstringMessage, message numberXX X
MESSAGEstringMessage textXXXX
LOG_NOstringApplication log: Log numberXXXX
LOG_MSG_NOstringApplication log: Message number running internally within logXXXX
MESSAGE_V1stringMessage, message variables

Up to four variable values
can be used in a message.


Variables are used in the same order as the
variables


appear in the message text

XXXX
MESSAGE_V2stringXXXX
MESSAGE_V3stringXXXX
MESSAGE_V4stringXXXX
PARAMETERstringName of parameter in which the error message occurredX   
ROWintRow in parameter in which the error message occurredX   
FIELDstringField in parameter in which the error message occurredX   
SYSTEMstringSystem (logical system) from which the message originatesX   

Table: Structure of ReturnParameters.</p>


4 Comments