首页 > 解决方案 > C# - KeyValueConfigurationCollection 的 Xml 反序列化

问题描述

我有一个 C# 应用程序。在这个应用程序中,我有一些如下所示的 XML:

string xml = @"<list name=""Groceries"">
  <add key=""1"" value=""Milk"" />
  <add key=""2"" value=""Eggs"" />
  <add key=""3"" value=""Bread"" />
</list>";

我正在尝试将此 XML 转换为 C# 对象。我的班级看起来像这样:

public class List : ConfigurationElement, IXmlSerializable
{
  [ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
  public string Name
  {
    get { return (string)(this["name"]); }
    set { this["name"] = value; }
  }

  [ConfigurationProperty("", IsRequired = false, IsKey = false, 
IsDefaultCollection=true)]
  public KeyValueConfigurationCollection Items
  {
    get
    {
      var items = base["items"] as KeyValueConfigurationCollection;
      return items;
    }
    set
    {
      if (base.Properties.Contains("items"))
      {
        base["items"] = value;
      }
      else
      {
        var configProperty = new ConfigurationProperty("items", typeof(KeyValueConfigurationCollection), value);
        base.Properties.Add(configProperty);
      }
    }
  }

  public XmlSchema GetSchema()
  {
    return this.GetSchema();
  }

  public void ReadXml(XmlReader reader)
  {
    this.DeserializeElement(reader, false);
  }

  public void WriteXml(XmlWriter writer)
  {
    this.SerializeElement(writer, false);
  }

    public static List Deserialize(string xml)
    {
        List list= null;

        var serializer = new XmlSerializer(typeof(List));
        using (var reader = new StringReader(xml))
        {
            list = (List)(serializer.Deserialize(reader));
        }

        return list;
    }

}

当我跑步时,var list = List.Deserialize(xml);我得到一个List对象。名称List设置正确。但是,Items属性是null。为什么不Items反序列化?如何Items使用列出的键/值对填充?

谢谢

标签: c#xml-serialization

解决方案


看起来与之前的问题重复。

以下是更正:

  • 从 getter 中删除“项目”,否则会抛出

System.Configuration.ConfigurationErrorsException:'属性'项目'不得从属性的 get 方法返回 null。通常,getter 应该返回 base[""]。'

get
        {
            var items = base[""] as KeyValueConfigurationCollection;
            return items;
        }
  • 更新了具有 root 属性的序列化程序:

public static List Deserialize(string xml)
    {
        var serializer = new XmlSerializer(typeof(List), new XmlRootAttribute("list"));
        List list = null;

        var xdoc = XDocument.Parse(xml);
        list = (List)serializer.Deserialize(xdoc.CreateReader());
        return list;
    }

最终版本现在如下:

public class List : ConfigurationElement, IXmlSerializable
{
    public List()
    { }

    [ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
    public string Name
    {
        get { return (string)(this["name"]); }
        set { this["name"] = value; }
    }

    [ConfigurationProperty("", IsRequired = false, IsKey = false,
  IsDefaultCollection = true)]
    public KeyValueConfigurationCollection Items
    {
        get
        {
            var items = base[""] as KeyValueConfigurationCollection;
            return items;
        }
        set
        {
            if (base.Properties.Contains("items"))
            {
                base["items"] = value;
            }
            else
            {
                var configProperty = new ConfigurationProperty("items", typeof(KeyValueConfigurationCollection), value);
                base.Properties.Add(configProperty);
            }
        }
    }

    public XmlSchema GetSchema()
    {
        return this.GetSchema();
    }

    public void ReadXml(XmlReader reader)
    {
        this.DeserializeElement(reader, false);
    }

    public void WriteXml(XmlWriter writer)
    {
        this.SerializeElement(writer, false);
    }

    public static List Deserialize(string xml)
    {
        List list = null;
        var serializer = new XmlSerializer(typeof(List), new XmlRootAttribute("list"));

        var xdoc = XDocument.Parse(xml);
        list = (List)serializer.Deserialize(xdoc.CreateReader());
        return list;
    }
}

推荐阅读