I've got a wcf service set up on the server which is supplying data to a flex project built using Flashbuilder4. I've used the webservice introspection feature to generate the DTOs and service proxies. One of the DTOs has a property of type Object. The contents of this generic object will vary based on certain conditions but will always be another complex object. Creating and populating the vo in FB4 goes smoothly but when the object is serialised it looks like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/s开发者_如何学运维oap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<tns:GetC xmlns:tns="EP2ProblemDemo1">
<tns:anyObj>
<tns:Property1>yo!</tns:Property1>
<tns:Property2>yo! yo!</tns:Property2>
</tns:anyObj>
</tns:GetC>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Where you might notice the anyObj property is missing any sort of type information despite referencing an object of type ClassB:
public class ClassA
{
public string Property1;
}
public class ClassB : ClassA
{
public string Property2;
}
The anyObj argument for GetC is missing something like the following:
xsi:type="tns:ClassB" xmlns:tns="EP2ProblemDemo1"
Which in turn produces an error when the wcf service tries to decode the message. I think the service is interpreting the contents of anyObj as an array which cannot be implicitly converted to a base object?
When setting the anyObj argument (of type Object) to an instance of ClassB it seems that the type information is lost. Is this correct behaviour? I was under the impression that even though you may set a superclass variable to reference one of it's subclasses the type information of the subclass should be retained and therefore also included in the serialised representation of that object.
EDIT It seems like the FlashBuilder4 serializer strips out concrete type and namespace info from a property of type Object when sending back to the wcf service which then cannot deserialize what looks to it like an array. Also, when importing a WSDL file in FB4, VO inheritance is lost as they ultimately extend EventDispatcher in order to be bindable.
SOLUTION My Solution was to change tack and move towards Remoting with AMF, implemented in .NET using FluorineFXFluorineFX official website which works beautifully and has the pleasant side effect of lower bandwidth consumption due to data being transmitted as byte array.
I believe WebORBWebORB official site can also be used to implement AMF in .net too but I've not tried it yet.
You can't use "any" object. You must always explicitly describe which types are allowed. Check KnownTypeAttribute and ServiceKnownTypeAttribute or DataContractResolver (I don't have too much experience with this yet). If you really need to send arbitrary data and you cannot define all possible object upfront use XElement instead. In xsd it will be described as xsd:any.
For all the object types that you send across the network, you need to set an attribute called [DataContract]
[DataContract] public class ClassA { public string Property1; }
Instead of using basic type (object) you should use a baseclass and make use of [KnownType] attribute
[ServiceContract(Namespace = "EP2ProblemDemo1")] public interface IService { [OperationContract] ClassC GetC(ClassD classB); }
[KnownType(typeof(ClassA)), KnownType(typeof(ClassB))] public class ClassD { }
Hope this helps
精彩评论