【问题标题】:C# - XML Deserialization of propertiesC# - 属性的 XML 反序列化
【发布时间】:2017-01-09 08:52:30
【问题描述】:

我找不到没有 getter 的属性无法正确解析的原因,让我给你写一个例子:

对于 XML 格式

<request>
  <job 
     mode="modefirst"
  />
<request>

我正在尝试使用属性将其反序列化为 POCO:

    private ESomeEnum emode;

    [XmlAttribute(AttributeName = "mode")]
    public string Mode
    {
       set { ESomeEnum.TryParse( blah blah );
    }

emode 在类构造函数中被设置为默认值,同时反序列化(System.Xml.Serialization 没有自定义类,只是在这里尝试简约)上面的 xml,永远不会调用 setter,但是当 property ' Mode' 包含一个 getter

    get { return this.emode.ToString(); }

setter 在反序列化过程中实际上被命中并设置了正确的值。

为什么会出现这种情况?有什么原因吗?

【问题讨论】:

标签: c# xml serialization


【解决方案1】:

XmlSerializer 仅处理具有公共 get-set 访问器的属性。但是你可以通过实现IXmlSerializable来自定义任何东西:

public class MyXmlSerializableClass : IXmlSerializable
{
    private ESomeEnum emode = ESomeEnum.modefirst;

    public string Mode
    {
        set { emode = ESomeEnum.Parse(value); }
    }

    public int ReadWriteProperty { get; set; }

    public int SemiReadOnlyProperty { get; private set; }

    private int backingFieldOfRealReadOnlyProperty;
    public int RealReadOnlyProperty
    {
        get { return backingFieldOfRealReadOnlyProperty; }
    }

    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        if (reader.Settings != null && !reader.Settings.IgnoreWhitespace)
        {
            reader = XmlReader.Create(reader, new XmlReaderSettings { IgnoreWhitespace = true });
            reader.Read();
        }

        reader.ReadStartElement();
        Mode = reader.ReadElementContentAsString("Mode", String.Empty);
        ReadWriteProperty = reader.ReadElementContentAsInt("ReadWriteProperty", String.Empty);
        SemiReadOnlyProperty = reader.ReadElementContentAsInt("ReadOnlyAutoProperty", String.Empty);
        backingFieldOfRealReadOnlyProperty = reader.ReadElementContentAsInt("ReadOnlyProperty", String.Empty);
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("Mode", emode.ToString());
        writer.WriteElementString("ReadWriteProperty", ReadWriteProperty.ToString(CultureInfo.InvariantCulture));
        writer.WriteElementString("ReadOnlyAutoProperty", SemiReadOnlyProperty.ToString(CultureInfo.InvariantCulture));
        writer.WriteElementString("ReadOnlyProperty", RealReadOnlyProperty.ToString(CultureInfo.InvariantCulture));
    }

    #endregion

    internal MyXmlSerializableClass()
    {/*needed for deserialization*/
    }
}

【讨论】:

  • 所以简而言之接口的默认配置是只反映ReadWriteProperties,我应该先看一下源码。感谢这个很好的例子,我会用它作为起点。
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多