8.3 Datatype Conversions

As with Java, ColdFusion, and PHP, Flash Remoting allows several ASP.NET native types to be passed and converted to ActionScript datatypes. Table 8-2 shows a list of ASP.NET datatypes and how they are converted to ActionScript datatypes and vice versa. Datatype conversion is bidirectional, unless more than one ActionScript type is converted to a given ASP.NET type (see the Null and Hashtable ASP.NET types).

Table 8-2. ASP.NET-to-ActionScript datatype conversions

ASP.NET datatype

ActionScript datatype

Double

Number

Bool

Boolean

String

String

Hashtable

ActionScript object

Null

Null

Null

Undefined

Array

Ordered (integer-indexed) array

Hashtable

Associative (named) array

DateTime

Date object

Hashtable

XML object

DataView/DataTable

RecordSet

Flash Remoting transforms most native ASP.NET datatypes into a comparable ActionScript datatype. However, complex ASP.NET types, such as classes and structures, are converted into Flash objects with only the properties intact by means of the ASObject, which I cover later in this chapter. This means that ASP.NET objects that depend on methods to access properties will not work once converted to ActionScript datatypes in your Flash application.

Flash also provides supports for arrays, but native arrays only. Complex ASP.NET array objects such as the ListArray, Enumerable, and StringDictionary cannot be converted into Flash objects. Considering the size and scope of the .NET Base Class Library, it would be impossible to list all unsupported datatypes. As a rule of thumb, if it's not in the list provided in Table 8-2, it's not supported. However, see Tables Table A-5, Table A-6, Table A-7, and Table A-8 in Appendix A, which show datatype conversions between ActionScript and C# or Visual Basic.NET in more detail.

8.3.1 Receiving Complex Datatypes from .NET

The Flash Remoting gateway allows .NET to build an ActionScript object and return it to Flash. Provided the necessary steps are taken, Flash Remoting can return ActionScript objects with custom types (rather than creating generic ASObjects only). For example, if we've defined and registered a custom ActionScript class, Book, we can create an ASObject of the Book type and access the returned data intact from our Flash application. Let's see how this is done.

Example 8-1 shows the client-side ActionScript to define our Book class with three properties (title, author, and price) and a single method, bookCost( ), in Flash.

Example 8-1. Declaring a custom class and registering it for remote usage
function Book ( ) {
  this.title = "";
  this.author = "";
  this.price = 0;
}

Book.prototype.bookCost = function (qty) {
  return (this.price * qty);
};

Object.registerClass("BookClass", Book);

Notice that the ActionScript code registers the object with Flash as a Book type. This is used to recreate objects of the Book class when they are returned from the .NET service. Now that we've seen the client-side implementation, let's look at the server side.

In the Flash Remoting for .NET implementation, the ASObject object inherits from a .NET Hashtable object and consists of the following important property and method:

ASType

The ASType property takes a string that identifies the name of the ASObject's Flash counterpart. This is explained in the following example.

Add( )

The Add( ) method adds name/value pairs to an ASObject. The method accepts two parameters: a name and its corresponding value, such as Add("Name", "Value"). Note that both the name and value must be strings. To retrieve a value, use syntax similar to an array. In C#, specify the name of the value to retrieve surrounded by brackets, such as myASObject["Name"]. In VB.NET, use parentheses, such as myASObject("Name").

To return an object through Flash Remoting, we need to define an instance of ASObject in the FlashGateway.IO namespace. With the object created, we can define the ASType our object will use. Here we define a remote method called GetBook( ) that creates and returns a Book object to Flash:

using System;
using FlashGateway.IO;

namespace FRDG {
  public class BookAssembly {
    public ASObject GetBook ( ) {
       ASObject aso = new ASObject( );
       aso.ASType = "Book";
       aso.Add("title", "FRDG");
       aso.Add("author", "Tom Muck");
       aso.Add("price", "39.99");
       return aso;
    }
  }
}

The Flash Remoting adapter converts our ASObject into the corresponding ActionScript object?in this case, an object of type Book?on the Flash client.

Flash Remoting does not return an object to Flash if the ASType property is not set. If nothing else, set ASType to "Object", which generates a generic instance of the Object class for return to the Flash client.

The final piece of the puzzle is to create the client-side ActionScript that acts as a callback function to receive the Book object from the .NET service:

function GetBook_Result (Results) {
  // Display the book's title and the cost of one dozen copies
  trace(Results.title);
  trace(Results.bookCost(12));
}

Now invoke the .NET remote method as follows:

#include "NetServices.as"

var myURL = "http://localhost/frdg/flashservices/gateway.aspx";
var servicename = "FRDG.BookAssembly";

NetServices.setDefaultGatewayURL(myURL);
var connection = NetServices.createGatewayConnection( )
var bookService = connection.getService(servicename, this);

bookService.GetBook( );

Once our GetBook_Result( ) callback handler receives the object, it calls the bookCost( ) method and traces the book's cost in the Output window (in this case, it displays the cost of a dozen books).

8.3.2 Sending Complex Datatypes to .NET

Flash Remoting also has strong support for sending complex datatypes from Flash to .NET applications. This feature is typically used to pass classes or structures as parameters to a .NET method.

First, we declare the object on the client side. The ActionScript code is the same as shown in Example 8-1 in the previous section.

When you pass a complex ActionScript object to a .NET remote method, it arrives as an object of type ASObject. The following C# class defines an InsertBook( ) method that accepts an ASObject but accesses the object's properties as if it were a Book object. We access the object's properties by specifying the name of the property to retrieve in quotes. In C#, surround the property name in brackets; in VB.NET, use parentheses.

using System;
using FlashGateway.IO;

namespace FRDG
{
  public class BookService
  {
    public bool InsertBook (ASObject asbook)
    {
      string title = asbook["title"].ToString( );
      string author = asbook["author"].ToString( );
      decimal price = (decimal)asbook["price"];

      // Code to insert book into database, or similar, is omitted

      // Return a successful status.
      return true;
    }
  }
}

Notice that the properties' names are always specified as strings and the values are stored as objects of the generic Object type. We must convert the title and author properties to strings using the ToString( ) method supported by all .NET objects. To convert the price property to a number, we explicitly cast it by using (decimal) before the object.

Invoke the service as you would any other Flash Remoting service. Simply create a Book object and pass it into the InsertBook( ) method, as shown in the following client-side ActionScript code:

#include "NetServices.as"

var myURL = "http://localhost/frdg/flashservices/gateway.aspx";
var servicename = "FRDG.BookService";

NetServices.setDefaultGatewayURL(myURL);
var connection = NetServices.createGatewayConnection( )
var bookService = connection.getService(servicename, this);

book = new Book( );
book.title = "ASP.NET Development with Dreamweaver MX";
book.author = "Joel Martinez";
book.price = 30.00;

bookService.InsertBook(book);

The ability to send and retrieve objects of custom datatypes is valuable when you're creating an object-oriented architecture for your application.

8.3.3 Convert Custom Classes to an ASObject

The .NET framework has a robust Reflection API. Reflection allows you to peer into the inner workings of any .NET class. Because of this, we can create a generic function that can accept any .NET class and convert its public properties into an ASObject. Here is a small utility function, written in C#, for converting a .NET class or struct into an ASObject for easy transmission to Flash:

using System;
using System.Reflection;
using FlashGateway.IO;

public class Util
{
  public static ASObject ConvertToASO (Object obj, string astype)
  {
    Type type = obj.GetType( );

    // Initialize the ASObject
    ASObject aso = new ASObject( );
    aso.ASType = astype;

    // Iterate through the member fields
    foreach(FieldInfo field in type.GetFields( ))
    {
      aso.Add(field.Name, field.GetValue(obj));
    }

    return aso;
  }
}

Note that the preceding code extracts only public fields, those intended to be exposed by the developer.

The ConvertToASO( ) function accepts two parameters. The first is of type Object, so you can pass any type of object into it. The second is a string used to represent the ActionScript type.

To demonstrate its usage, we create a struct of type Book in C# (notice it has the same properties as the ActionScript object we constructed in earlier examples):

public struct Book
{
  public string title;
  public string author;
  public decimal price;
}

Call the ConvertToASO( ) function whenever you need to return an object to Flash. The following method, written in C#, instantiates a new Book object and sets its properties. It then uses ConvertToASO( ) to convert the struct to an ASObject:

public ASObject GetABook( )
{
  Book book = new Book( );
  book.title = "FRDG";
  book.author = "Tom Muck";
  book.price = 39.99

  ASObject aso = Util.ConvertToASO(book,"Book");

  return aso;
}

8.3.4 Receiving Arrays from .NET

Flash Remoting also supports native .NET arrays but does not support complex array types such as Lists and Collections.

.NET can create a native array from any set of variables with the same type. The disadvantage of an array is that it requires a developer to provide a list of the objects within the array. This prevents the array from dynamically expanding past a preset size.

To create an array in .NET, use the [ ] operator. Initialize (a.k.a. dimension) the array with the desired number of elements. For example, here is some C# code to initialize an array:

String[] nameArray = new String[5];

You can initialize the array with literals by immediately providing a list of the items you'd like store in it:

String[] nameArray = new String[]{"Joel Martinez", "Tom Muck"};

By default, specifying an array literal sets the maximum number of elements to the number of items specified, but we can set a maximum while initializing only a few array elements:

String[] nameArray = new String[5]{"Joel Martinez", "Tom Muck"};

Access the .NET objects from the array using a zero-relative numeric index. Here we change the value of the first two elements of the array:

nameArray[0] = "Angelina Jolie";
nameArray[1] = "Lara Croft";

Like in ActionScript, all .NET array indexes start from 0, not 1. This means the first element in our array will always be 0, so the previous array has 2 full slots.

.NET arrays provide support for all native .NET datatypes, including structures and classes. We can create an array of ASObject objects and return the array to Flash, which is a convenient way to return more than one object, such as an array of search results, to Flash. The following C# code creates an ASObject array with two indexes and stores two Books as elements of the array (technically, it converts the Book objects to ASObjects and stores the ASObjects in the array):

using System;
using FlashGateway.IO;

namespace FRDG {
  public class BookService {
    public ASObject[] GetBookList ( ) {
      ASObject[] asoArray = new ASObject[2];

      Book bookItem0 = new Book( );
      bookItem0.title = "Flash Remoting: The Definitive Guide";
      bookItem0.author = "Tom Muck";
      asoArray[0] = Util.ConvertToASO(bookItem0);

      Book bookItem1 = new Book( );
      bookItem1.title = "ActionScript Cookbook";
      bookItem1.author = "Joey Lott";
      asoArray[1] = Util.ConvertToASO(bookItem1);

      return asoArray;
    }
  }
}

As with our complex objects, Flash automatically converts our .NET array to ActionScript's array datatype. The developer can immediately access the array's values from the Results object returned by our Flash Remoting service. In the following client-side ActionScript code snippet, our Flash application displays the title of the first book in the array returned by our Flash Remoting services' GetBookList( ) method:

#include "NetServices.as"

var myURL = "http://localhost/frdg/flashservices/gateway.aspx";
var servicename = "FRDG.BookService";

NetServices.setDefaultGatewayURL(myURL);
var connection = NetServices.createGatewayConnection( )
var bookService = connection.getService(servicename, this);

bookService.GetBookList( );

function GetBookList_Result (Results) {
  trace(Results[0].title);
}

You can view the array and Book objects by opening Flash's interactive debugger. For more information on debugging, see Chapter 13.

8.3.5 Sending Arrays to .NET

Sending arrays as a parameter from Flash to a .NET application is straightforward. We can build an array of any of our supported datatypes and pass those values to .NET. For example, to pass an array of strings containing book titles to our .NET application, we could use the following client-side ActionScript code:

#include "NetServices.as"

var myURL = "http://localhost/frdg/flashservices/gateway.aspx";
var servicename = "FRDG.BookService";

NetServices.setDefaultGatewayURL(myURL);
var connection = NetServices.createGatewayConnection( )
var bookASPnetService = connection.getService(servicename, this);

bookTitleArray = new Array( );
bookTitleArray[0] = "FRDG";
bookTitleArray[1] = "ASDG2";

bookASPnetService.AddTitles(bookTitleArray);

Our .NET application can receive this array and access it as a native array object:

public void AddTitles (string[] books) {
  foreach (string book in books) {
    // statements...
  }
}

Flash Remoting also allows Flash to create arrays of complex objects to pass to a .NET application. For example, we can use the ActionScript Book class, which we defined earlier, to create several instances of a Flash object and pass them all as parameters to our .NET service. Here is the client-side ActionScript code the invokes the remote AddBooks( ) method, shown next:

bookArray = new Array( );

bookItem = new Book( );
bookItem.title = "FRDG";
bookItem.author = "Tom Muck";
bookArray[0] = bookItem;

bookItem = new Book( );
bookItem.title = "ASDG2";
bookItem.author = "Colin Moock";
bookArray[1] = bookItem;

// The code to initialize bookASPnetService is shown in the preceding example
bookASPnetService.AddBooks(bookArray);

Once our designated .NET method receives the parameter, it can access the array of objects natively. The following .NET code snippet shows the remote AddBooks( ) method iterating through the array of objects:

public void AddBooks (ASObject[] books)
{
  foreach (ASObject book in books)
  {
    // Do something with each individual "book"
  }
}

Naturally, you can use the methods and properties of the .NET Array class to perform operations on the array or its elements. For example, the Array.GetLength( ) method returns the length of the array (the number of elements in the array). Refer to the .NET resources cited in Appendix B for more information on .NET's Array class.



    Part III: Advanced Flash Remoting
     
    ASPTreeView.com
     
    Evaluation has ГЛЦ№µјexpired.
    Info...