集合接口和WCF

时间:2010-11-10 03:55:49

标签: c# .net wcf

我正在使用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)。

4 个答案:

答案 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:

  1. 必须有无参数构造函数
  2. 必须有添加方法。
  3. 当我实施这些问题时,我的问题就消失了。

答案 2 :(得分:0)

您必须在DataContract类定义前面加PropertiesCollection

 [DataContract]
 class PropertiesCollection:IEnumerable<KeyValuePair<string, object>>
 {
    ...
 }

进入序列化的每种类型都应为[DataContract][Serializable]

答案 3 :(得分:0)

最简单的解决方案:

  1. 创建包含键和值的新的可序列化类
  2. 在任何集合中传递此类