Accessibility

Table of Contents

Communicating between Flex and .NET

Communicating using Remoting

Remoting is the Flash Player's implementation of Remote Procedure Calls (RPCs) using a proprietary binary protocol called Action Message Format (AMF). Remoting is fast and compact. It supports sending and receiving strongly typed, custom objects. It will even handle nested custom objects and multiple references to a single object. However, while Flash Player will encode and send your calls in AMF, you will need to set up a Remoting gateway on your .NET server to receive and handle your RPCs (see Figure 3).

While Remoting via the Flash Player uses a binary protocol, it is not related to .NET Remoting, which uses a different proprietary binary protocol or SOAP serialization. The two remoting implementations are not interchangeable, require separate connections and serializers, and are used for different situations. Remoting discussed here is specifically targeted towards integration with Flex whereas .NET Remoting is useful only for communication between .NET applications.

The Remoting model

Figure 3. The Remoting model

Luckily, there are many Remoting gateway implementations available for multiple platforms for you to use, including some that are free and some that are open source. For the purposes of this tutorial, you will use The Silent Group's Fluorine, a .NET gateway, freely available at the Fluorine page. Installing and setting up Fluorine will be covered later in this section. There are other .NET solutions available, such as WebORB (.NET, Java, Ruby on Rails) and AMF.NET.

Before using Remoting in Flex, you need to make sure that any custom objects you plan on passing back and forth are set up to map properly to their counter-parts in .NET. Simple types are automatically converted, but custom objects require a little bit of attention. You may recall that earlier in this article, when the common example was explained, the ActionScript custom value objects had [RemoteClass(alias="")] tags above them. These tags let the Remoting gateway know how to map the custom objects. For the mappings to work, you must provide two things. First, for every custom object in ActionScript, you must make a corresponding .NET object with identical field names and matching field types. Second, you must provide the fully qualified name of this object in the alias field of the RemoteClass tag, which must be placed before the definition of each ActionScript object you use. The following table shows how Fluorine maps simple ActionScript types to .NET types and vice-versa:

Flash/Flex Type .NET Type
Number Any numeric type, as appropriate
Array object array, IList, ArrayList
String System.String
Object object
Boolean System.Boolean
Date System.DateTime
XML System.Xml.XmlDocument
Undefined null

Table 3. How Fluorine maps simple ActionScript types to .NET types and vice-versa

Once your objects are set up, making a Remote Procedure Call is very simple in Flex. There are multiple methods available for making a Remoting call in Flex. For this tutorial, you will use the Flash Player's built in NetConnection class. You can use NetConnection to connect to a gateway and call remote functions. Whereas HTTP and Web services were described in MXML, when working with NetConnection you will need to use ActionScript. Unlike NetConnection, the HTTPService and WebService classes are a part of the Flex framework and are set up through properties, making them easy to work with in MXML. NetConnection is a Flash Player class and connects and sets up parameters through function calls rather than properties, so ActionScript must be used. After instantiating a NetConnection, provide the object's connect() method with the URL of your Remoting gateway. Once connected, you can use the call() method to make RPCs. The call() method takes two parameters and a …rest array. The first parameter is the fully qualified name of the .NET function you are calling in the form of a String. The second parameter is a flash.net.Responder object that defines the functions to call with the result and with any faults that occur. Finally, any other parameters you specify will be sent to the remote function you are invoking. The following code is an example AMF call:

private function callAmfService():void
    {
     netConn = new NetConnection();
     netConn.connect("http://localhost/AmfService/Gateway.aspx");
     netConn.call("RosterAMFService.GetRoster", 
          new Responder(amfServiceResultHandler), studentStepper.value);
}

The gateway page for this Remoting call is a file called Gateway.aspx, which will be the default gateway in any Fluorine web site you set up. A gateway page is a dummy page whose contents are never actually viewed. Fluorine intercepts requests made to the gateway page and processes them as Remoting calls. The NetConnection calls a .NET function called GetRoster in the .NET class RosterAMFService. The Responder passed in is set to call a function called amfServiceResultHandler when the RPC returns a result. If a second parameter were to be passed to Responder's constructor, that function would be called if a fault occurred. It should be noted that any exceptions that are thrown in .NET will be logged by Fluorine and propagate across Remoting as a fault in Flex. Finally, the third parameter is the value of a UI numerical stepper, passed in because the function GetRoster (which you will see later) takes a single argument in the form of an integer.

Handling the result of the call is a piece of cake. Your result handler will receive a parameter of the same type that the remote function returns, mapped from .NET to ActionScript. So if your .NET function returns a string, the handler will receive a String, and if it returns a ClassData object (as in this example), the handler will receive an ActionScript ClassData object (provided that the RemoteClass tag is properly in place). This makes handling results a breeze, as you are ready to work with the results immediately once they are returned:

private function amfServiceResultHandler(result:ClassData):void {
     updateUI(result);
}

If you go back and compare this result handler to the handlers involved in the HTTP service and web service examples, there is absolutely no contest in terms of programmer friendliness.

The next portion of this section will concentrate on setting up the .NET side for Remoting. Fluorine, the Remoting gateway of our choice, can be downloaded from the aforementioned website in the form of a friendly windows installer. The first thing that you will notice once the installation is that a new kind of project has become available in Visual Studio 2005. Selecting File > New > Web Site > Fluorine ASP.NET Web Application, as the name implies, you create a fully functional AMF service. The bin folder already contains all the necessary .dll files, namely, com.TheSilentGroup.Fluorine.dll, com.TheSilentGroup.Fluorine.ServiceBrowser.dll, and log4net.dll. The first two libraries are the Fluorine foundation, while the last file serves for logging purposes. Additionally, the Web.config file has additional tags: <sectionGroup name="fluorine">, <httpModules>, and <fluorine>, and a log4net.config file is also created. A file named Gateway.aspx is empty and never executed, but it is required to prevent ASP.NET from throwing a File not found exception. The .cs file created by default has the main Fluorine library already imported, along with the [RemotingService] tag added on top of the class definition. The code of the service used in our example is listed below:

[RemotingService]
public class RosterAMFService
{
   public static ClassData GetRoster(int numStudents)
   {
       ClassData sampleClass = new ClassData();
       sampleClass.ClassName = "Science";
       sampleClass.TeacherName = "Smith";
       sampleClass.TeacherID = 10;
       sampleClass.Students = new List<StudentData>();
       for (int i = 0; i < numStudents; i++)
       {
           StudentData student = new StudentData();
           student.StudentID = i + 1;
           if (i % 2 == 0)
           {
               student.StudentName = "Denis";
           }
           else
           {               
               student.StudentName = "Alexey";
           }
           sampleClass.Students.Add(student);
       }
       return sampleClass;
   }
}

There are barely any differences between this code and the code of the web or the HTTP service listed above. In fact, the difference between the web service code is only in the tag above the line with class declaration. As we can see, the .NET side setup of Remoting turns out to be more complicated in only one thing: Fluorine installation. Since it has to be performed only once and takes less than a minute, it can hardly be considered a disadvantage.