【问题标题】:C# - Serializing private property as attribute (Data Contract)C# - 将私有属性序列化为属性(数据协定)
【发布时间】:2017-03-26 10:34:59
【问题描述】:

在得知我无法序列化类中的私有属性后,我开始使用 DataContractDataMember 注释。

我的类中有一个私有字符串属性,我想将其序列化为属性而不是元素。

[DataContract]
public class Channel
{
    private string m_Name = string.Empty;
    private DateTime? m_TxTime = null;

    [DataMember, XmlAttribute("name")]
    public string Name
    {
        get
        {
            return m_Name;
        }
        set
        {
            m_Name = value;
        }
    }

    public DateTime? TxTime
    {
        get
        {
            return m_TxTime;
        }
        set
        {
            m_TxTime = value;
        }
    }

    [DataMember, XmlAttribute("txTime")]
    private string txTimeForSerialization
    {
        get
        {
            if (TxTime.HasValue)
            {
                return TxTime.Value.ToString("o");
            }
            else
            {
                return null;
            }
        }
    }
}

尝试同时使用 DataMemberXmlAttribute 注释给了我这个输出:

<channel name="NAME">
   <TxTime>2017-03-26T13:15:56.8042989+03:00</TxTime>
</channel>

我想要的结果是这样的-

<channel name="NAME" txTime="2017-03-26T13:15:56.8042989+03:00" />

我序列化的方式是使用 XmlSerializer -

using (FileStream fs = new FileStream("channels.txt", FileMode.Create))
{
    XmlSerializer serializer = new XmlSerializer(typeof(Channel));
    serializer.Serialize(fs, objectName);
}

【问题讨论】:

标签: c# serialization datacontract datamember


【解决方案1】:

为您的类创建“包装器”,它将负责正确的反序列化格式(某种外观模式)

[DataContract]
public class ChannelData
{
    [DataMember, XmlAttribute("name")]
    public string Name { get; set; }

    [DataMember, XmlAttribute("txTime")]
    public string txTimeForSerialization { get; set; }
}

您可以将创建序列化实例的逻辑放在Channel 类中,然后序列化逻辑将保留在 Channel 类中 - 保持封装。

public class Channel
{
    public string Name { get; set; }
    public DateTime? TxTime { get; set; }

    public Channel()
    {
        Name = string.Empty;
        TxtTime = null;
    }

    public ChannelData ToSerialization()
    {
        var data = new ChannelData();
        data.Name = Name;
        data.txTimeForSerialization = TxTime.HasValue ? TxTime.Value.ToString("o") : null;
    }
}

使用包装器,您无需为不同的格式考虑不同的“解决方法”,您的“业务层”类将保持“清晰”,而包装器将处理格式。

【讨论】:

    【解决方案2】:

    如果您想坚持使用当前的Channel 类,则需要实现IXmlSerializer 接口及其WriteXml 方法。这是您可以通过XmlSerializer 序列化私有属性的唯一方法。

    public class Channel : IXmlSerializable
    {
        private string m_Name = string.Empty;
        private DateTime? m_TxTime = null;
    
        public string Name
        {
            get
            {
                return m_Name;
            }
            set
            {
                m_Name = value;
            }
        }
    
        public DateTime? TxTime
        {
            get
            {
                return m_TxTime;
            }
            set
            {
                m_TxTime = value;
            }
        }
    
        private string txtTimeForSerialization
        {
            get
            {
                if (TxTime.HasValue)
                {
                    return TxTime.Value.ToString("o");
                }
                else
                {
                    return null;
                }
            }
        }
    
        public XmlSchema GetSchema()
        {
            return null;
        }
    
        public void ReadXml(XmlReader reader)
        {
            //implement reader if needed...
        }
    
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("name", this.Name);
            writer.WriteAttributeString("txtTime", this.txtTimeForSerialization);
        }
    }
    

    通过实现IXmlSerializable,您不再需要使用属性,并且您写入channels.txt的代码将保持不变:

    using (FileStream fs = new FileStream("channels.txt", FileMode.Create))
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Channel));
        serializer.Serialize(fs, objectName);
    }
    

    这是输出:

    <?xml version="1.0"?>
    <Channel name="NAME" txtTime="2017-03-26T12:57:25.6780078Z" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      相关资源
      最近更新 更多