【发布时间】:2017-08-10 20:50:13
【问题描述】:
我正在尝试设置 WCF 服务以将有关复杂对象 SimCalibrationData 的信息传递给客户端。 SimCalibratonData 包含 SimCalibrationBaseData 类型的对象列表。 SimCalibrationBaseData 具有 SimPlateData 类型的对象。所有类都用 [DataContract] 修饰,公共属性用 [DataMember] 修饰。如果我将 SimPlateData 对象包装到 List 中,我可以将它们发送给我的客户端并且它们被成功反序列化。如果我不包装它们,我会收到一条错误消息“服务器未提供有意义的回复”,并提示可能存在合同不匹配。
我读过列表和其他集合总是可以序列化和反序列化,但是如果我不想麻烦地将所有数据包装在列表中,我还没有找到任何信息告诉我该怎么做。
这是我的服务器端代码:
[DataContract]
public class SimCalibrationData
{
private List<SimBaseCalibrationData> m_baseCalibrations = new List<SimBaseCalibrationData>();
[DataMember]
public List<SimBaseCalibrationData> BaseCalibrations
{
get { return m_baseCalibrations; }
}
public SimCalibrationData(CSimThermalCalibrationList calibrationList)
{
foreach (CSimThermalCalibration calibration in calibrationList.Listing)
{
m_baseCalibrations.Add(new SimBaseCalibrationData(calibration));
}
}
}
[DataContract]
[KnownType(typeof(SimPlateData))]
public class SimBaseCalibrationData
{
// Plate Parameters
SimPlateData m_convectorPlate;
[DataMember]
public SimPlateData ConvectorPlate
{
get { return m_convectorPlate; }
}
SimPlateData m_loadPlate;
[DataMember]
public SimPlateData LoadPlate
{
get { return m_loadPlate; }
}
public SimBaseCalibrationData(CSimThermalCalibration calibration)
{
m_convectorPlate = new SimPlateData(calibration.ConvectorPlate);
m_loadPlate = new SimPlateData(calibration.LoadPlate);
}
}
[DataContract]
public class SimPlateData
{
public SimPlateData(CSimPlate plate)
{
}
}
感谢您的帮助。同时,我会将所有内容都包装在列表中。
【问题讨论】:
-
关于 DataContracts 的几点说明。首先,您要序列化的每个属性都需要同时具有 get 和 set - 否则序列化将失败(没有 setter,发送方无法序列化该值)。其次,除非您在客户端和服务之间共享具有数据协定的程序集,否则方法和构造函数对您没有任何好处,因为这些项目不可序列化。只涉及数据。
-
感谢您的回复。那么,我不明白在序列化过程中发生了什么。服务器端有一个构造函数,可以将我的生产数据转换为将要发送的对象。这将初始化我的数据成员。但是您是说序列化将创建我的对象的副本并仅复制公共数据成员而不调用构造函数? (实际上,这听起来很熟悉。我似乎记得在某个地方读过。)
-
是的,这是正确的,根据我的理解和经验。 DataContract 所做的只是告诉系统使用 DataContractSerializer,它将序列化所有标有
[DataMember]的属性。构造函数和方法不会被序列化或发送过来。这是 SOA 原则 - 实现由客户决定。