Understanding the iframecall.axd handler
Most guys that have been using ATLAS till now haven’t had the time (or patience) for understanding how the communication between the client and the server is handled, ie, for most guys, it just works! Though I’ve followed this path many times before, I decided to take some time and understand what’s going on when you start a remote request from the page (ie, when you use Javascript to get info from a local or remote server).
Let’s start from the beginning (ie, from the cliente side)…ATLAS’ client platform has the notion of executor: a class whose sole purpose is to call a remote site (server side of the app or remote application) and get the necessary info. Currently, the platform defines two types of executors: XMLHttpExecutor e IFrameExecutor. Both these classes extend the abstract WebRequestExecutor class.
Both executors perform the server side calls asynchronously. Btw, nothing prevents you from developing your own executor. For instance, let’s say you have a scenario where you need to perform a synchronous server call: you can’t do it with none of the predefined executors so you might build your own which could do just that. Going back to the executors, it’s fairly obvious to understand how they work by looking at their names: the first (XMLHttpExecutor) uses the XmlHttpRequest object to communicate with the server side; on the other hand, the second (IFrameExecutor) uses an iframe to get the necessary data from the server. In this post, I’ll just talk about this second executor.
In the last days, I’ve seen that there’s been an increase in the number of questions related with remote web service invocation. Looking at the docs, you may think that you’re only option is to use a bridge or build your own web service which wraps the remote call. Well, I’d say that there’s still another option, if you’re in control of the application which hosts the web service: use the IFrameExecutor to perform that remote call!
So, let’s go back to the beginning… if you’re using one of what I call “high level network” classes, most of the time the correct executor will be automatically picked up to perform a remote web method call. When the IFrameExecutor enters the game, you must configure the target remote application so that the IFrameCall.axd handler is on (by adding the necessary entry to the web.config file). This is needed because the IFrameExecutor depends on that handler to get the data in the correct format from the server. It’s important to note that IFrameHandler implements the IHttpAsyncHandler interface (indirectly) so that it can perform its work asynchronously. After getting the results from the web service, they’re packaged on a javascript object (serialized in JSON) and sent back to the client.
Well, nothing new here. What most guys haven’t got yet is that the IFrameHandler must be activated on the site that is hosting the remote web service and not in the one that has the page that is making the call. Let me give you an example. Let’s suppose that application A has a page (PA) that is trying to invoke a remote web service (WS) which is hosted at a remote web site (B). If you want to, you can invoke this remote service from the client side of page PA by using the IFrameExecutor. However, for it to work, you really need to ATLAS-enable site B and activate the iframecall.axd handler because IFrameExecutor will call that handler to get the result. Unfortunately, most guys think that they need to activate iframecall.axd in site A (which is wrong) and then end up thinking that remote services can’t be called from the client side of page.
One more note: most of the client components which perform remote calls have a property called appURL which is really important and can be used to influence the site used by the executor. The correct configuration of this property might be important in some scenarios.
So, now you know: when you’re trying to invoke a remote web service and you’re getting an iframecall.axd related error start by checking if it’s enabled on the destination site.
Though this option may not be viable in all the scenarios, I really think that if you’re in control of the remote app you should use it because by doing this you are communicating directly from the client browser to the site that is hosting the web service (if you ask me, this is a lot better than calling the server side and then performing the remote method invocation).