C# – How to serialize objects in flex for a c# backend

actionscript-3apache-flexcserializationweb services

We are developing an app with a Flex frontend and a C# backend, connected through web services.
We are using the FLex Builder 3's Web Service Manager to autogenerate the webservice classes.
The problem araise when Flex serialize our objects, for example, when we have a Number property with no value, this is serialized as NaN, and our backend doesn't know about NaN. Another example is when we serialize a cyclic reference, we get a stack over flow exception.
I know in java, for example, you can configure the way xstream work with cyclic reference… So, the question is, can we change the way Flex serialize the objects so C# can work with this frontend? Is there any issue we should know about how flex serialize objects?
Thanks!
Jorge

Best Answer

I think you should consider a little different design, we also had similar problem but we developed following solution.

Only Primitive Arguments

Define only primitive types in Web Service Method Arguments (string, int) etc..

For example you have a class,

class Person{
    long PersonID;
    long MembershipID;
    string Name;
}

And you want to only change "Name" property on the backend, the truth is, you should not trust your Frontend, you should treat that frontend can easily be compromised and can send wrong data, like MembershipID in this case is the field not to be modified by frontend ever.

You may write your code that Person will save correctly, but someone can easily read WSDL and harm the code.

So instead of this.

[WebMethod] 
public void SavePerson(Person p){
    p.Save(); <-- this is dangerous
}

we use

[WebMethod] 
public void SavePersonName(long personID, string name){
    Person p = GetPersonByID(personID);
    p.Name = name;
    p.Save();
}

I know many will argue that this will cause more coding as well as more roundtrips to server, however roundtrips can also be avoided by using Specialized Wrapper Classes.

Use of Wrapper Classes in Arguments

// I will only define the fields I want to pass to server
// this needs to be done at backend level
class PersonAddressWrapper{
    long PersonAddressID;
    string AddressLine1;
    string AddressLine2;
    string ZipCode;
    string City;
    string Country;
}

class PersonWrapper{
    long PersonID;
    string Name;
    PersonAddressWrapper[] Addresses; 
}

[WebMethod]
public void SavePerson(PersonWrapper pw){
    Person p = GetPersonByID(pw.PersonID);
    p.Name = pw.Name;
    p.Save();
    foreach(PersonAddressWrapper paw in pw.Addresses){
        PersonAddress pa = GetPersonAddressByID(paw.PersonAddressID);
        Copy(pa,paw);
        pa.Save();
    }
}

This way you can reduce the round trips, you can also organize wrapper classes to include/exclude items that can remove your cyclic dependency and its safe too.

Yes I know it requires more work, but this is the safe method.