我正在使用C#和WCF来进行Web服务。我有一个实现IEnumerable的类的成员变量。我尝试将其作为数据合同的一部分进行序列化:
[DataContract]
class Item
{
[DataMember]
private IEnumerable<KeyValuePair<string, object>> Member1
{
get { return this._Properties; }
set { this._Properties = Value; }
}
}
_Properties的类型为:
class PropertiesCollection:IEnumerable<KeyValuePair<string, object>>
{
...
}
我认为WCF会将Member1序列化为IEnumerable,因为这是我给该成员的类型,但是我收到了InvalidDataContractExceptiom,并显示以下消息:
类型PropertyCollection无法序列化。请考虑使用DataContractAttribute属性对其进行标记,并使用DataMemberAttribute属性标记要序列化的所有成员。如果类型是集合,请考虑使用CollectionDataContractAttribute对其进行标记。有关其他受支持的类型,请参阅Microsoft .NET Framework文档。
WCF似乎正在查看通过Member1(PropertyCollection)传递的对象的运行时类型,而不是属性的类型(IEnumenable)。这种理解是否正确?将[CollectionDataContract]添加到PropertiesCollection是唯一的修复方法吗?如果可能的话,我更愿意将服务合同非特定(即它只知道iot是IEnumerable)。
答案 0 :(得分:1)
脱离我的头脑:我认为您需要使用KnownType属性修饰Member1
属性。
请参阅:http://msdn.microsoft.com/en-us/library/ms730167.aspx
[DataContract]
[KnownType(typeof(PropertiesCollection))] //<--- this guy here
class Item
{
[DataMember]
private IEnumerable<KeyValuePair<string, object>> Member1
{
get { return this._Properties; }
set { this._Properties = Value; }
}
}
在上面的链接中添加Example2中的代码,以显示即使属性是类装饰器,它也适用于DataMember:
public interface ICustomerInfo {}
[DataContract(Name = "Customer")]
public class CustomerTypeA : ICustomerInfo {}
[DataContract(Name = "Customer")]
public class CustomerTypeB : ICustomerInfo {}
[DataContract]
[KnownType(typeof(CustomerTypeB))] //<-- check it! This applies to 'buyer'
public class PurchaseOrder
{
[DataMember]
ICustomerInfo buyer;
[DataMember]
int amount;
}
答案 1 :(得分:1)
对于这个问题,真正的问题是,类型必须满足一些要求才能成为有效的集合DataContract:
当我实施这些问题时,我的问题就消失了。
答案 2 :(得分:0)
您必须在DataContract
类定义前面加PropertiesCollection
:
[DataContract]
class PropertiesCollection:IEnumerable<KeyValuePair<string, object>>
{
...
}
进入序列化的每种类型都应为[DataContract]
或[Serializable]
答案 3 :(得分:0)
最简单的解决方案: