我们有一个庞大的客户端/服务器WinForms应用程序,它使用.NET远程处理在层之间传递DAO,这有一些问题。
使用一个简单,设计和想象的例子,将改变对象:
public class Employee
{
public int ID;
public string Name;
public DateTime DateOfBirth;
}
到此:
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}
更改序列化格式,破坏与旧客户端的兼容性?
答案 0 :(得分:1)
重要编辑:这应该兼容并允许绑定?
public class Employee
{
private int id;
private string name;
private DateTime dateOfBirth;
public int ID { get {return id;} set {id = value;} }
public string Name { get {return name;} set {name = value;} }
public DateTime DateOfBirth { get {return dateOfBirth;}
set {dateOfBirth = value;} }
}
是的,如果客户端/服务器不同步,这将导致问题。
.NET远程处理使用BinaryFormatterm(没有定制的ISerializable
实现)使用字段名称。使用自动属性会破坏字段名称。
只要您同时更新客户端和服务器,它就应该可以工作。另一种选择是使用与名称无关的序列化,例如protobuf-net。如果您愿意,我可以提供一个示例(它支持ISerializable
用法)。
(顺便说一句,添加属性不会影响BinaryFormatter
,因为它是基于字段的)
根据要求,这是使用protobuf-net来控制远程序列化的示例(直接从我的unit tests之一获取);请注意,在客户端和服务器都同意之前,这也是不兼容的,但在此之后应该承受更改(它的设计非常易于扩展)。请注意,有很多方法可以使用它 - 显式成员表示法(如数据合同)或隐式字段(如BinaryFormatter
)等等(中间的所有内容)...这只是 one < / strong>使用它的方式:
[Serializable, ProtoContract]
public sealed class ProtoFragment : ISerializable
{
[ProtoMember(1, DataFormat=DataFormat.TwosComplement)]
public int Foo { get; set; }
[ProtoMember(2)]
public float Bar { get; set; }
public ProtoFragment() { }
private ProtoFragment(
SerializationInfo info, StreamingContext context)
{
Serializer.Merge(info, this);
}
void ISerializable.GetObjectData(
SerializationInfo info, StreamingContext context)
{
Serializer.Serialize(info, this);
}
}
这里,底部2方法满足ISerializable
,并简单地将执行传递给protobuf-net引擎。 [ProtoMember(...)]
定义字段(具有唯一标识标记)。如前所述,它也可以推断出这些,但它更明确更安全(更不易碎)。