AIF Error Microsoft.Dynamics.Ax.Xpp.InvalidRemoteCallException

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();
        }
    }

}

About erpcoder
Azure Cloud Architect and Dynamics 365 enthusiast working in Research & Development for InsideAx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: