Shifting to .NET Access Provider

This document gives guidance for the users of COM access provider on how to move their code to .NET access provider. The .NET Access Provider allows you do develop .NET based applications that interact with the processes and activities in the server. COM Access Provider is not supported any more by IFS. Therefore, developers could use the following guidelines to move their logic which uses COM to .NET based platform.

Apart from switching to a .NET based application and rewriting the application in a .NET language, there is also the option to use .NET Access Provider while using a COM client. Documentation to setup the .NET Access Provider for COM clients is found here.

This document describes how each activity followed in developing applications with COM access provider can be re-implemented using a .NET language and also by accessing .NET Access Provider while using a COM client. If there is a need to use DOCMAN macros you will have to follow a similar way as using .NET Access Provider while using a COM client. Developing DOCMAN macros using .NET Access Provider is also described in this document.

At the end of this document there are three complete examples of the same implementation done using

  1.     COM Access Provider
  2.     .NET Access Provider from a .NET language
  3.     .NET Access Provider from a COM language.
  4.     .NET Access Provider from DOCMAN macros.

Installation

COM AP Run the IFS COM Access provider Installer
.NET AP from .NET language Run the IFS .NET Access Provider.msi using ".NET Access Provider" option. .NET assemblies will then be downloaded to your computer.
.NET AP from COM language Run the IFS .NET Access Provider.msi using ".NET Access Provider Extension for COM clients" option. Type libraries will then be installed to your computer.
.NET AP from DOCMAN macro Run the IFS .NET Access Provider.msi using ".NET Access Provider Extension for COM clients" option. Type libraries will then be installed to your computer.

 

Adding references

COM AP Adding reference to IFS COM Access Provider type library.
.NET AP from .NET language There is no type library. You have to add reference to the dlls. You can add references through the IDE (as in COM-AP) or specify them in the compilation command if the command prompt is used.

csc /reference:Ifs.Fnd.AccessProvider.dll;Ifs.Fnd.Data.dll;Ifs.Fnd.Core.dll PLSQLQueries.cs

(In that case the referenced dlls must be located in the same directory as the source file.)

.NET AP from COM language Adding references to .NET Access Provider type libraries.
.NET AP from DOCMAN macro Adding references to .NET Access Provider type libraries.

 

Creating a server connection

COM AP Creating an instance of Server class
Dim oServer As New Server

By default it will display the login dialog to prompt for credentials. In case you need to avoid having the login dialog you need to set the connection through the code as following.
oServer.ConnectionString = "<server_url>"
oServer.SetCredentials "<identity>", "<password>"
.NET AP from .NET language Need to create an instance of FndConnection. Using the following constructor will prompt for username and password to the server.

FndConnection conn = new FndConnection(pars[0]);

You can give credentials to the server through code by using the following constructor.

FndConnection conn = new FndConnection(pars[0], pars[1], pars[2]); -> The second and third parameters being the username and the password.

Note: If IFS login dialog need to be used an instance of FndLoginDialog could be used. Ifs.Fnd.AccessProvider.Interactive.dll should be referenced in order to use FndLoginDialog. Credentials could be stored and retrieved from isolated storage as well.

FndConnection conn = new FndConnection();

// Get stored credentials from isolated storage
FndLoginCredentials lc = FndLoginDialog.GetStoredCredentials();

FndLoginDialog dlg = new FndLoginDialog(conn);
dlg.ShowDialog(lc, true);

// Save changed setting in isolated storage
FndLoginDialog.StoreCredentials(lc);

.NET AP from COM language Same classes are accessed with different syntax. Since COM does not support passing parameters to constructors, connection string and credentials have to be set explicitly.

Dim conn As New FndConnection

conn.ConnectionString = "<server_url>"
conn.SetCredentials "<identity>", "<password>"

If credentials are not specified you will be shown the login dialog to enter credentials.

.NET AP from DOCMAN macro Same implementation as using a COM language but with different syntax.

Dim oServer

Set oServer = CreateObject("Ifs.Fnd.AccessProvider.FndConnection")
oServer.ConnectionString = "<server_url>"

oServer.SetCredentials "<identity>", "<password>"

 

Defining the command

COM AP The classes used are PlsqlSelectCommand, PlsqlCommand, PlsqlBaseMethodCommand and PlsqlCommandCollection
.NET AP from .NET language Similar classes are used for similar purposes; FndPLSQLSelectCommand, FndPLSQLCommand, FndPLSQLBaseMethodCommand and FndPLSQLCommandCollection.
.NET AP from COM language Same classes are used; FndPLSQLSelectCommand, FndPLSQLCommand, FndPLSQLBaseMethodCommand and FndPLSQLCommandCollection.
.NET AP from DOCMAN macro Same as in COM language

 

Properties of command objects

Properties of PlsqlSelectCommand, PlsqlCommand and PlsqlBaseMethodCommand in COM-AP, such as BindVariables, CommandText and Server exist in .NET-AP as well in a similar manner. Following code examples show that defining a command is quite similar in both COM-AP and .NET AP.

COM AP Dim oCmd As New PlsqlSelectCommand
Set oCmd.Server = oServer
oCmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC"
oCmd.BindVariables.Add "DESC", "A%"
.NET AP from .NET language  FndPLSQLSelectCommand cmd = new FndPLSQLSelectCommand(conn)
cmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC"

cmd.BindVariables.Add(new FndBindVariable(FndBindVariableDirection.In, "DESC", new FndTextAttribute("A%")));

.NET AP from COM language Dim oTxtAttr As New FndTextAttribute
oTxtAttr.SetValue ("A%")

Dim oBindVar As New FndBindVariable
oBindVar.Direction = FndBindVariableDirection.FndBindVariableDirection_In
oBindVar.Name = "DESC"
Set oBindVar.Value = oTxtAttr

Dim oCmd As New FndPLSQLSelectCommand
oCmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC"
Set oCmd.Connection = conn
oCmd.BindVariables.Add oBindVar
.NET AP from DOCMAN macro Set oFndTextAttr = CreateObject("Ifs.Fnd.Data.FndTextAttribute")
oFndTextAttr.SetValue "A%"

Set oBindVarDesc = CreateObject("Ifs.Fnd.AccessProvider.PLSQL.FndBindVariable")
oBindVarDesc.Direction = 0
oBindVarDesc.Name = "DESC"
oBindVarDesc.Value = oFndTextAttr


Set oSelectCmd = CreateObject("Ifs.Fnd.AccessProvider.PLSQL.FndPLSQLSelectCommand")
oSelectCmd.Connection = oFndConnection oSelectCmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC"
oSelectCmd.BindVariables.Add (oBindVarDesc)

 

Invoking the server operation

COM AP Execute method of all command classes and ExecuteQuery method of PlsqlSelectCommand are used to execute the command. The result returned is assigned to a RecordCollection object.
Dim oResult As RecordCollection
Set oResult = oCmd.ExecuteQuery
.NET AP from .NET language   The corresponding methods to execute the command are ExecuteReader method of FndPLSQLSelectCommand and ExecuteNonQuery method of FndPLSQLCommand. (Since FndPLSQLSelectCommand and FndPLSQLBaseMethodCommand are inherited from FndPLSQLCommand ExecuteNonQuery method could be used by any command instance.) ExecuteReader returns a set of results and the result can be assigned to a FndDataTable instance.

 

FndDataTable table = cmd.ExecuteReader("FND_USER");

FND_USER is the type of records in the resultset; i.e the name of the database table or view.

.NET AP from COM language

 

Dim oTable As FndDataTable

Set oTable = oCmd.ExecuteReader_3("FND_USER")

 

Please note that you need to use ExecuteReader_3 because COM languages does not identify overloaded methods and hence we need to specify that it is the third overloaded method that has to be accessed.

.NET AP from DOCMAN macro Set oFndDataTable = CreateObject("Ifs.Fnd.Data.FndDataTable")
Set oFndDataTable = oSelectCmd.ExecuteReader()

 

Handling the result

COM AP  In order to iterate through the RecordCollection retrieved COM-AP uses Record object.
Dim oUser As Record
Dim sMsg As String

' Read result into message
For Each oUser In oResult
sMsg = sMsg & oUser.Attributes("DESCRIPTION").Value & vbCrLf
Next

' Show message
MsgBox sMsg

 
.NET AP from .NET language   In order to iterate and manipulate the resultset assigned to FndDataTable instance there are lot of Data types available under Ifs.Fnd.Data namespace, like FndDataColumn, FndDataRow, FndDataColumnCollection, FndBoolAttribute and FndDateAttribute. To iterate over the FndDataTable instance a simple “For” loop could be used.

for(int i = 0; i < table.Rows.Count; i++)
{
  strText = strText + Console.WriteLine(table.Rows[i]["DESCRIPTION"].ToString()) + “ “;
}

MessageBox.Show(strText);

.NET AP from COM language

 

Dim oRow As FndDataRow

Dim oDesAttr As FndTextAttribute

For intCounter = 0 To oTable.Rows.Count - 1
       Set oRow = oTable.Rows.Item(intCounter)
       Set oDesAttr = oRow.Item(1)
       sMsg = sMsg & oDesAttr.ToString() & vbCrLf
Next
MsgBox sMsg

Please note that if there are indexers defined the first indexer is only taken into account. For example FndDataRow class is indexed by types int, string and FndDataColumn. But since the first indexer encountered is the integer indexer that is the only indexer that can be used by COM. Hence oTable.Rows.Item(intCounter) is used.

.NET AP from DOCMAN macro For Each Row In oFndDataTable.Rows
              text = text & Row.Item(1) & vbCrLf
Next
MsgBox sMsg
 

 

Exception Handling

COM AP By default, the COM access provider will catch any server errors that occur and show an error message. In order to do further handling you could check for the return value of the operation and handle accordingly.
If oCmd.Execute Then
 Debug.Print “Execution successful”
Else
 Debug.Print "Error in Execution"  

 

 

Else, you could turn off automatic error catching of the server and handle exceptions yourself.

oServer.CatchExceptions = False
On Error GoTo InvokeErrHandler
 oServer.Invoke "Activity_Setup_Application_Users", "Get_Application_User", oRecUser
On Error GoTo 0
You can write your own code for InvokeErrHandler. “On Error GoTo 0” statement will turn error trapping off.

.NET AP from .NET language   The .NET Access Provider uses .NET native way of handling exceptions. The exceptions thrown are of FndException class or of one of its subclasses. If you need to handle exceptions in your own way you could simply catch it and write code for what you need to do.

try
{
 // Do stuff
}
catch(FndException err)
{
 err.Show();
}

.NET AP from COM language Automatic error catching can be turned off using CatchExceptions property

 

conn.CatchExceptions = False

.NET AP from DOCMAN macro Same as in COM language.

 

Activity queries and Activity commands

COM AP COM access provider supports to invoke activities defined in the server

oServer.Invoke "ClientApplication", "IdentifyCurrentUser", oRecUser

.NET AP from .NET language   The same functionality can be achieved by the .NET access provider using the classes defined in Ifs.Fnd.AccessProvider.Activity namespace
.NET AP from COM language Invoking activities can be defined in the following way

conn.InvokeByCom "ClientApplication", "IdentifyCurrentUser", oRecUser

Note that when accessing .NET AP from a COM client InvokeByCom method should be used.

.NET AP from DOCMAN macro Same as in COM language.

 

Few things to remember

            conn.InteractiveMode = false;

 

Additional features

.NET AP has the advantage of making use of the IFS debug console so that troubleshooting is easier. You have to add reference to Ifs.Fnd.Diagnostics.dll, set DebugSettings.DebugMode property of FndConnection instance to true and use FndDebugMonitor.StartDebugMonitor() to start the debug console. But please note that using the IFS debug console is not possible when accessing .NET AP from a COM client.

 

Complete code examples of the implementation of retrieving user details.

Option Explicit

Sub Main()
Dim oServer As New Server
' Uncomment the following two lines to avoid connect dialog
'oServer.ConnectionString = "<server_url>"
'oServer.SetCredentials "<identity>", "<password>"

Dim oCmd As New PlsqlSelectCommand
Set oCmd.Server = oServer
oCmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC"
oCmd.BindVariables.Add "DESC", "A%"
Dim oResult As RecordCollection
Set oResult = oCmd.ExecuteQuery

Dim oUser As Record
Dim sMsg As String

' Read result into message
For Each oUser In oResult
sMsg = sMsg & oUser.Attributes("DESCRIPTION").Value & vbCrLf
Next

' Show message
MsgBox sMsg

End Sub
using System;
using System.Windows.Forms;
using Ifs.Fnd;
using Ifs.Fnd.Data;
using Ifs.Fnd.AccessProvider;
using Ifs.Fnd.AccessProvider.PLSQL;

public abstract class UserDetails
{
	private static FndConnection conn;

	public static void Main(string [] pars)
	{
		try
		{ 
			// If you want to have a login dialog, use constructor with only first parameter instead. 2nd and 3rd parameters are username and password.
			conn = new FndConnection(pars[0], pars[1], pars[2]);
			// I set CatchExceptions = false since I'm in a try block
			conn.CatchExceptions = false;

			FndPLSQLSelectCommand cmd = new FndPLSQLSelectCommand(conn, "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC");
			cmd.BindVariables.Add(new FndBindVariable(FndBindVariableDirection.In, "DESC", new FndTextAttribute("A%")));

			FndDataTable table = cmd.ExecuteReader("FND_USER");
			String strText = "";

			for(int i = 0; i < table.Rows.Count; i++)
			{
				strText = strText + table.Rows[i]["DESCRIPTION"].ToString() + "\n";

			}
			MessageBox.Show(strText);

		}
		catch(FndException err)
		{
			err.Show();
		}
	}
}

Option Explicit


Sub Main() Dim conn As New FndConnection conn.ConnectionString = "<server_url>" conn.SetCredentials "<identity>", "<password>" conn.CatchExceptions = False Dim oTxtAttr As New FndTextAttribute oTxtAttr.SetValue ("A%")
Dim oBindVar As New FndBindVariable oBindVar.Direction = FndBindVariableDirection.FndBindVariableDirection_In oBindVar.Name = "DESC" Set oBindVar.Value = oTxtAttr
Dim oCmd As New FndPLSQLSelectCommand oCmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC" Set oCmd.Connection = conn oCmd.BindVariables.Add oBindVar
Dim oTable As FndDataTable Dim oRow As FndDataRow
Set oTable = oCmd.ExecuteReader_3("FND_USER")
Dim sMsg As String Dim intCounter As Integer Dim oDesAttr As FndTextAttribute For intCounter = 0 To oTable.Rows.Count - 1 Set oRow = oTable.Rows.Item(intCounter) Set oDesAttr = oRow.Item(1) sMsg = sMsg & oDesAttr.ToString() & vbCrLf Next ' Show message MsgBox sMsg
End Sub
Sub TestMac1()

Dim oFndConnection, oSelectCmd
Dim text As String

Set oFndConnection = CreateObject("Ifs.Fnd.AccessProvider.FndConnection")
'oFndConnection.CatchExceptions = False
oFndConnection.ConnectionString = "<server_url>"

Set oSelectCmd = CreateObject("Ifs.Fnd.AccessProvider.PLSQL.FndPLSQLSelectCommand")
oSelectCmd.Connection = oFndConnection
Set oBindVarDesc = CreateObject("Ifs.Fnd.AccessProvider.PLSQL.FndBindVariable")
Set oFndTextAttr = CreateObject("Ifs.Fnd.Data.FndTextAttribute")
oFndTextAttr.SetValue "A%"

Set oFndDataTable = CreateObject("Ifs.Fnd.Data.FndDataTable")

oBindVarDesc.Direction = 0
oBindVarDesc.Name = "DESC"
oBindVarDesc.Value = oFndTextAttr

oSelectCmd.CommandText = "SELECT * FROM FND_USER WHERE DESCRIPTION LIKE :DESC"

oSelectCmd.BindVariables.Add (oBindVarDesc)

Set oFndDataTable = oSelectCmd.ExecuteReader()


For Each Row In oFndDataTable.Rows
text = text & Row.Item(1) & vbCrLf
Next
MsgBox text, vbOKOnly


End Sub