AIF Error Microsoft.Dynamics.Ax.Xpp.InvalidRemoteCallException
25. November 2013 Leave a comment
There are many reasons why an AIF Service call might fail, and I also ran into one. The task was to refactor existing code that processes some business logic and renames a file to .OLD. The original code looked like this
public class ERPProcessFile
{
Filename fileName;public static void main(Args args)
{
ERPProcessFile pf = new ERPProcessFile(args);
pf.run();
}public void new(Args _args)
{
if(_args && _args.parm())
fileName = _args.parm();
else
throw error(error::missingParameter(null));
}private void run()
{
#File
FileIOPermission permission;if(fileName != "")
{
permission = new FileIOPermission(fileName,#io_write);
permission.assert();
WinAPI::moveFile(fileName,strFmt(‘%1.old’,fileName));
CodeAccessPermission::revertAssert();
}
}
}
The code above was tested using a Job
static void Job1(Args _args)
{
Args args = new Args();
args.parm(@"C:\Users\Public\Documents\textfile.txt");ERPProcessFile::main(args);
}
The code was wrapped in a service class and published as AIF HTTP web service
class ERPProcessFileService
{
[SysEntryPointAttribute]
public void processFile(Filename _localFile)
{
Args args = new Args();
args.parm(_localFile);ERPProcessFile::main(args);
}
}
The service was published to IIS, and imported in Visual C# as Ax2012 namespace
var context = new Ax2012.CallContext();
context.MessageId = Guid.NewGuid().ToString();var client = new Ax2012.ERPProcessFileServiceClient();
client.ClientCredentials.Windows.ClientCredential =
new System.Net.NetworkCredential("USER", "PW", "DOMAIN");
client.processFile(context,@"C:\Users\Public\Documents\textfile.txt");
The service call resulted in an exception
{"Exception of type ‘Microsoft.Dynamics.Ax.Xpp.InvalidRemoteCallException’ was thrown."}
The reason was the use of WinAPI class which does not work when executed on the AOS. However, the code works fine when tested using a Job, or called within a Form. The solution was easy; Checking if the code is executed on Server or Client and using WinAPI or WinAPIServer class.
public class ERPProcessFile
{
Filename fileName;public static void main(Args args)
{
ERPProcessFile pf = new ERPProcessFile(args);
if(xGlobal::clientKind() == ClientType::Client)
pf.run();
if(xGlobal::clientKind() == ClientType::Server)
pf.runServer();
}public void new(Args _args)
{
if(_args && _args.parm())
fileName = _args.parm();
else
throw error(error::missingParameter(null));
}private void run()
{
#File
FileIOPermission permission;if(fileName != "")
{
permission = new FileIOPermission(fileName,#io_write);
permission.assert();
WinAPI::moveFile(fileName,strFmt(‘%1.old’,fileName));
CodeAccessPermission::revertAssert();
}
}private void runServer()
{
#File
FileIOPermission permission;if(fileName != "")
{
permission = new FileIOPermission(fileName,#io_write);
permission.assert();
WinAPIServer::copyFile(fileName,strFmt(‘%1.old’,
fileName));
WinAPIServer::deleteFile(fileName)
CodeAccessPermission::revertAssert();
}
}}