Kev*_*her 3 c# wcf interface dto automapper
我有一个类,其中有一些嵌套类.我将它序列化并使用一种没有问题的方法将其发送到wcf服务.这是班级;
public class ComputerDTO
{
[DataMember]
public ComputerTypeDTO Type { get; set; }
[DataMember]
public string ComputerName { get; set; }
[DataMember]
public MonitorDTO Monitor { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是方法;
public void Check()
{
Computer c = new Computer();
ISystemInfoOperations cli = GetServiceClient();
Mapper.CreateMap<Monitor, MonitorDTO>();
Mapper.CreateMap<IHardwarePart, IHardwarePartDTO>();
Mapper.CreateMap<Computer, ComputerDTO>()
.ForMember(s => s.Hardware, m => m.MapFrom(q => Mapper.Map<List<IHardwarePart>, List<IHardwarePartDTO>>(q.Hardware)));
Mapper.AssertConfigurationIsValid();
ComputerDTO dto = Mapper.Map<Computer, ComputerDTO>(c);
string sendComputerInfo = cli.SendComputerInfo(dto);
}
Run Code Online (Sandbox Code Playgroud)
但是我还有一个要发送的接口列表.所以我改变了下面的代码并得到一个错误.
public class ComputerDTO
{
[DataMember]
public ComputerTypeDTO Type { get; set; }
[DataMember]
public string ComputerName { get; set; }
[DataMember]
public MonitorDTO Monitor { get; set; }
[DataMember]
public List<IHardwarePartDTO> Hardware { get; set; }
}
public interface IHardwarePartDTO
{
[DataMember]
string Name { get; set; }
[DataMember]
HardwarePartTypeDTO PartType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
硬件内部正在填补项目.但是,如果我尝试发送它,我会得到这个着名的错误:
:数据合同名称"_x0030__Culture_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<IHardwarePartDTO> Hardware { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您可以根据需要添加任意数量的已知类型属性.
ServiceKnownTypes属性稍微复杂一些.这非常相似,但您可以将其添加到服务类中.
除此之外,您可以使用数据合同解析器 - 但这非常复杂,需要一段时间才能解释.
编辑:18/02/2013 15:11
您可能还需要查看Automapper,因为它当前将在您的硬件列表中创建代理 - 并且代理无法序列化.您需要告诉automapper将它们序列化的内容 - 例如:
Mapper.CreateMap<Monitor, MonitorDTO>();
Mapper.CreateMap<Monitor, IHardwarePartDTO>().As<MonitorDTO>();
Mapper.CreateMap<Audio, AudioDTO>();
Mapper.CreateMap<Audio, IHardwarePartDTO>().As<AudioDTO>();
Mapper.CreateMap<CDROMDrive, CDROMDriveDTO>();
Mapper.CreateMap<CDROMDrive, IHardwarePartDTO>().As<CDROMDriveDTO>();
//you need entries like these for everythin that implements IHardwarePartDTO
Run Code Online (Sandbox Code Playgroud)
这样,automapper就知道它需要创建什么.