使用DataContractSerializer序列化接口列表

我有一个类,其中有一些嵌套类。 我将它序列化并使用没有问题的方法将其发送到wcf服务。 这是class级;

public class ComputerDTO { [DataMember] public ComputerTypeDTO Type { get; set; } [DataMember] public string ComputerName { get; set; } [DataMember] public MonitorDTO Monitor { get; set; } } 

这是方法;

 public void Check() { Computer c = new Computer(); ISystemInfoOperations cli = GetServiceClient(); Mapper.CreateMap(); Mapper.CreateMap(); Mapper.CreateMap() .ForMember(s => s.Hardware, m => m.MapFrom(q => Mapper.Map<List, List>(q.Hardware))); Mapper.AssertConfigurationIsValid(); ComputerDTO dto = Mapper.Map(c); string sendComputerInfo = cli.SendComputerInfo(dto); } 

但是我还有一个要发送的接口列表。 所以我更改下面的代码并得到一个错误。

 public class ComputerDTO { [DataMember] public ComputerTypeDTO Type { get; set; } [DataMember] public string ComputerName { get; set; } [DataMember] public MonitorDTO Monitor { get; set; } [DataMember] public List Hardware { get; set; } } public interface IHardwarePartDTO { [DataMember] string Name { get; set; } [DataMember] HardwarePartTypeDTO PartType { get; set; } } 

硬件内部正在填补项目。 但如果我尝试发送它,我会得到这个着名的错误:

输入数据合同名称为“_x0030__Cult_x003D_neutral_PublicKeyToken_x003D_null_x003E_: http : //schemas.datacontract.org/2004/07/Proxy%3CSystemInfo.DTO.IHardwarePartDTO_SystemInfo.DTO_Version=1.0.0 ”的“代理”。 考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 – 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

DataContractSerializer需要知道可能返回的具体类型。 接口无法序列化,因为它无法反序列化(如何在没有具体实现的情况下创建接口实例)。

简单的解决方案是添加如下所示的KnownTypes属性:

 [KnownType(typeof(your hardware dto concrete type here))] public class ComputerDTO { [DataMember] public ComputerTypeDTO Type { get; set; } [DataMember] public string ComputerName { get; set; } [DataMember] public MonitorDTO Monitor { get; set; } [DataMember] public List Hardware { get; set; } } 

您可以根据需要添加任意数量的已知类型属性。

ServiceKnownTypes属性稍微复杂一些。 这非常相似,但您可以将其添加到服务类中。

除此之外,您可以使用数据合同解析器 – 但这非常复杂,需要一段时间才能解释。

编辑:18/02/2013 15:11

您可能还需要查看Automapper,因为它当前将在您的硬件列表中创建代理 – 并且代理无法序列化。 您需要告诉automapper将它们序列化的内容 – 例如:

 Mapper.CreateMap(); Mapper.CreateMap().As(); Mapper.CreateMap(); Mapper.CreateMap().As(); Mapper.CreateMap(); Mapper.CreateMap().As(); //you need entries like these for everythin that implements IHardwarePartDTO 

这样,automapper就知道它需要创建什么。