WCF DataContract只读属性的序列化?

时间:2009-08-27 20:25:21

标签: wcf serialization

每当我使用WCF时,我总是尝试创建最终通过线路的不可变类(即在构造函数中设置的参数,属性是只读的)。但是,这会妨碍WCF序列化,这要求所有属性都是Public get / set(这是有道理的,因为它必须反序列化它们)

即使在this related post中,我也看到他们的解决方案最终将所有内容都设为公开,这违反了我的良好编程意识。有没有办法解决?我是否必须满足于这种解决方案或类似冰棒不变性的东西并对它感到满意?

我试过的另一件事是这样的,我有一个基类用于所有东西,一个派生类使得这个集合没用:

/// <summary>
/// This represents a discovered virtual-machine template that can be
/// instantiated into a RunningVirtualMachine
/// </summary>
[DataContract]
[XmlRoot("VMTemplate")]
public class VirtualMachineTemplateBase
{
    [DataMember]
    public virtual ulong SizeInBytes { get; set; }
}

/// <summary>
/// This class is the real guts of VirtualMachineTemplate that we're hiding
/// from the base class.
/// </summary>
[XmlInclude(typeof(VirtualMachineTemplateBase))]
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
{
    ulong _SizeInBytes;
    public override ulong SizeInBytes {
        get { return _SizeInBytes; }
        set { }
    }
}

2 个答案:

答案 0 :(得分:15)

如果您使用DataContractSerializer(这是WCF的默认设置),您可以序列化使用[DataMember]属性修饰的任何内容 - 甚至是只读字段:

[DataContract]
public class VirtualMachineTemplate : VirtualMachineTemplateBase, IXmlPicklable, IEnableLogger
{
    [DataMember]
    ulong _SizeInBytes;
}

但您需要使用DataContractSerializer - 而不是XML序列化程序。 XML序列化程序只能序列化公共属性(除非你在它们上放一个[XmlIgnore],否则它将会。)

DataContractSerializer与众不同:

  • 它不需要无参数默认构造函数
  • 序列化您使用[DataMember]
  • 明确标记的内容
  • 但这可以是任何东西 - 字段,属性和任何可见性(私有,受保护,公共)
  • 它比XmlSerializer快一点,但是你无法控制XML的形状 - 你只能对所包含的内容有所了解

有关更多提示和技巧,请参阅此blog post和此blog post

马克

答案 1 :(得分:3)

为了确保不变性和易于实现,同时为属性添加私有setter以进行反序列化。在发动机罩下发生了很多事情,但它确实有效。