处理WCF中DataContract的复杂情况

时间:2011-05-31 15:33:04

标签: .net wcf serialization datacontract

有关WCF中DataContract(s)的数千个问题,特别注意涉及继承的情况。 但是,我没有找到关于我将在这里提供的所有概述的具体情况的例子。

考虑将以下DataContract应用于WCF服务通信中使用的类型(代码清单1)

// Data contract for my comm type
[DataContract]
public class MyCommsType {
   [DataMember]
   public Type1 field1;
   [DataMember]
   public Type2 field2;
   [DataMember]
   public Type1 field3;
   [DataMember]
   public Type2 field4;
   [DataMember]
   public List<Type2> field5;
   [DataMember]
   public List<Type1> field6;
}
// Used types
public class Type1 {
   ...
}
public class Type2 {
   ...
}

这种类型应该在这里使用(代码清单1.1)

[ServiceContract]
public interface IMyService {
   [OperationContract]
   string CommOp1(MyCommType mct);
   [OperationContract]
   MyCommType CommOp2(string s);
}

我的个人类型MyCommsType是涉及通讯的类型。但是,当然,CLR不知道如何序列化它,因为它不是基类库中的本机类型。 MyCommsType需要数据合同,所以我提供了它。然而,这种艺术水平还不足以让事情发挥作用(没有什么能像这样!!)。

为什么不起作用?那是因为,在MyCommsType里面有未知的类型吗?

那么,我应该执行以下(代码清单2)

// Data contract for my comm type
[DataContract]
[KnownType(typeof(Type1))]
[KnownType(typeof(Type2))]
[KnownType(typeof(List<Type1>))]
[KnownType(typeof(List<Type2>))]
public class MyCommsType {
   [DataMember]
   public Type1 field1;
   [DataMember]
   public Type2 field2;
   [DataMember]
   public Type1 field3;
   [DataMember]
   public Type2 field4;
   [DataMember]
   public List<Type2> field5;
   [DataMember]
   public List<Type1> field6;
}

是否正确????

但是,如果它是正确的,CLR如何知道如何序列化Type1Type2 ????? 我从未在这两种类型中添加属性???? 我是否必须放置[Serializable],如此处所示(代码清单3)

// Used types
[Serializable]
public class Type1 {
   ...
}
[Serializable]
public class Type2 {
   ...
}

如何应对这种情况?

为了简化(回答),请考虑以下问题:

1)代码清单1 是否完全解决了序列化问题?

1a)如果没有,那么,如何处理这个问题?

2)在案例1)没问题的情况下,如何处理Type1Type2的序列化问题? [Serializable]应用程序是否解决?

1 个答案:

答案 0 :(得分:4)

您的问题可以通过更简单的方式解决。

无论您使用何种类型,您只需将其序列化即可。更简单的解决方案是将您的子类作为数据自身合同。

例如,如果你有

// Data contract for my comm type  
[DataContract]  
public class MyCommsType {     
[DataMember]     public Type1 field1;     
[DataMember]     public Type2 field2;     
[DataMember]     public Type1 field3;     
[DataMember]     public Type2 field4;     
[DataMember]     public List<Type2> field5;     
[DataMember]     public List<Type1> field6;  
}  

确保Type1和Type2是Datacontracts。这就是你需要做的一切。

[DataContract]
public class Type1 {...}

[DataContract]
public class Type2 {...}

如果您正在执行任何类型的Inherence,则可能需要放置KnownType属性。否则只需将子类型(Type1和Type2)保持为Datacontracts即可。