我在服务器上设置了一个wcf服务,该服务为使用Flashbuilder4构建的flex项目提供数据。我使用了webservice introspection功能来生成DTO和服务代理。其中一个DTO具有Object类型的属性。此通用对象的内容将根据特定条件而有所不同,但始终是另一个复杂对象。在FB4中创建和填充vo很顺利,但是当对象被序列化时,它看起来像这样:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/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>
尽管引用了ClassB类型的对象,但您可能会注意到anyObj属性缺少任何类型的信息:
public class ClassA
{
public string Property1;
}
public class ClassB : ClassA
{
public string Property2;
}
GetC的anyObj参数缺少以下内容:
xsi:type =“tns:ClassB”xmlns:tns =“EP2ProblemDemo1”
当wcf服务尝试解码消息时,这又会产生错误。我认为该服务将anyObj的内容解释为一个不能隐式转换为基础对象的数组?
当将anyObj参数(类型为Object)设置为ClassB的实例时,似乎丢失了类型信息。这是正确的行为吗?我的印象是,即使您可以设置一个超类变量来引用它的子类之一,也应该保留子类的类型信息,因此也包含在该对象的序列化表示中。
修改 似乎FlashBuilder4序列化程序在发送回wcf服务时从Object类型的属性中删除具体类型和命名空间信息,然后无法反序列化类似于数组的内容。此外,在FB4中导入WSDL文件时,VO继承会丢失,因为它们最终会扩展EventDispatcher以便可绑定。
解 我的解决方案是改变方向并转向使用AMF进行远程处理,使用FluorineFX FluorineFX official website在.NET中实现,它工作得很漂亮,并且由于数据以字节数组的形式传输而具有较低带宽消耗的令人愉快的副作用。
我相信WebORB WebORB official site也可用于在.net中实现AMF,但我还没有尝试过。
答案 0 :(得分:0)
您不能使用“任何”对象。您必须始终明确说明允许哪些类型。检查KnownTypeAttribute和ServiceKnownTypeAttribute或DataContractResolver(我对此还没有太多经验)。如果您确实需要发送任意数据,则无法预先定义所有可能的对象,而是使用XElement。在xsd中,它将被描述为xsd:any。
答案 1 :(得分:0)
对于通过网络发送的所有对象类型,您需要设置一个名为[DataContract]的属性
[DataContract] 公共课ClassA { public string Property1; }
您应该使用基类并使用[KnownType]属性
而不是使用基本类型(对象)[ServiceContract(Namespace =“EP2ProblemDemo1”)] 公共接口IService { [OperationContract的] ClassC GetC(ClassD classB); }
[KnownType(typeof(ClassA)),KnownType(typeof(ClassB))] 公共类ClassD { }
希望这有帮助