How to fix - The server-side impersonated (RunAs) session tried to invoke a method that is available for client-side processing only

Recently, I was asked to help with an issue in one of our development environments. The scenario was that we were importing bank statements in text format into Dynamics AX and then creating a log file on the system.

I was told that this code was working fine but all of a sudden they were seeing the below error when running the process in batch.

The server-side impersonated (RunAs) session tried to invoke a method that is available for client-side processing only.

The above error occurs only when a code running on Server tries to call a code which is bound to run on client. So whats the bigs issue, you will ask? Why cant the server code call the client code. This will be a problem only when there is no open client. For example, code is running in batch on the server and there is no open client.

To fix this, they had overridden the runsImpersonated() method and were explicitly returning false.

I explained them that, this meant that their batch code will run on the client instead of the server and this was beating the whole purpose of extending from the RunBaseBatch franework.

I traced the error call and it was being thrown from WinAPI::createFile()

I at once knew what the problem was. The WinAPI class is set to RunOn Client while the batch code was running on Server. So, in their case they don’t have a client to invoke this call.

They had two options now,

Either change the RunOn property of WinAPI to Server which they suggested and I rejected,

Use an alternate class. The alternate class in question here is WinAPIServer

Their earlier code was,

WinAPI::createFile(fileName, #OPEN_EXISTING, #GENERIC_WRITE);

I replaced that with,

WinAPIServer::createFile(fileName);

Now, after removing the runsImpersonated() override, we ran the code again in batch and this time we had a different error

Request for the permission of type 'FileIOPermission' failed.

This was coming from,

(S)\Classes\WinAPIServer\createFile - line 17

The issue here is that the method which we are using is a CAS enabled API. When it is running on the server, it needs permission to be asserted.

Since we were dealing with File IO, I created an object of FileIOPermission and asserted it.


fileIOPermission = new FileIOPermission(fileName, #io_write);
fileIOPermission.assert();

WinAPIServer::createFile(fileName);

That did it and the issue was solved.

Comments

RT said…
Hi,

Thank you for a very good post.

The winapi::createFile can be repalced with winapiserver::createFile, but how about winapi::findFirstFile and winapi:findNextFile?

Thanks.
RT said…
Hi,

Thank you for demystifying the client and server api.

However, I don't see replacements for winapi::findFirstFile and winapi::findNextFile? I need these to get all teh files in a network directory.

Thanks.
Mehul Thacker said…
Hi,

I have issue with "Why cant the server code call the client code. This will be a problem only when there is no open client. For example, code is running in batch on the server and there is no open client."

we can't call to client code from server code. while runsImpersonated returns true.
means, while executing code at server there is no way to call client side code even client is open.
Afsar said…
How can I delete the file which is created by non-admin user like the properties of the file are set to read-only.
Afsar said…
How can I delete the file which is created by non-admin user like the properties of the file are set to read-only.
Afsar said…
How can i delete the file via a WinAPIServer::deleteFile() if the file has attribute set to readonly permission? I got the FileIOPermission error while i tired your solution.

Popular posts from this blog

How to add empty ranges in query

The field with ID '0' does not exist in table - Cause and resolution.

Get selected records in Dynamics AX 2012