无法在 C# 中反序列化 XML - InvalidOperationException [英] Unable to Deserialize XML in C# - InvalidOperationException

查看:32
本文介绍了无法在 C# 中反序列化 XML - InvalidOperationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 C# 应用程序,它在 App.config 文件中有一个自定义的配置信息部分.此时,我可以通过代码成功加载自定义信息.但是,我也在尝试从数据库加载相同的配置信息.为了尝试这样做,我从我知道正在工作的 App.config 文件中获取了一个 XML 字符串.该 XML 字符串如下所示:

I have a C# app that has a custom section of configuration info in the App.config file. At this time, I am able to successfully load the custom info via code. However, I'm trying to load that same configuration info from a database as well. In an attempt to do this, I took a string of XML from my App.config file that I know is working. That string of XML looks like this:

<departments>
  <department id="1" name="Sporting Goods">
    <products>
      <product name="Basketball" price="9.99">
        <add key="Color" value="Orange" />
        <add key="Brand" value="[BrandName]" />
      </product>
    </products>
  </department>
</departments>

我正在尝试将此 XML 反序列化为 C# 对象.我已经像这样定义了这些对象:

I am trying to deserialize this XML into C# objects. I've defined these objects like this:

Departments.cs

public class Departments : ConfigurationSection
{
  private Departments() { }

  [ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
  public DepartmentItemCollection Items
  {
    get
    {
      var items = base[""] as DepartmentItemCollection;
      return items;
    }
    set { base["items"] = value; }
  }

  public static Departments Deserialize(string xml)
  {
    Departments departments = null;

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

    return departments;
  }
}

[ConfigurationCollection(typeof(Department), CollectionType = ConfigurationElementCollectionType.BasicMapAlternate)]
public class DepartmentItemCollection : ConfigurationElementCollection
{
  private const string ItemPropertyName = "department";

  public override ConfigurationElementCollectionType CollectionType
  {
    get { return ConfigurationElementCollectionType.BasicMapAlternate; }
  }

  protected override string ElementName
  {
    get { return ItemPropertyName; }
  }

  protected override bool IsElementName(string elementName)
  {
    return (elementName == ItemPropertyName);
  }

  protected override object GetElementKey(ConfigurationElement element)
  {
    return ((Department)element).Name;
  }

  protected override ConfigurationElement CreateNewElement()
  {
    return new Department();
  }

  public override bool IsReadOnly()
  {
    return false;
  }
}

Department.cs

public class Department : ConfigurationElement
{
  public Department()
  { }

  [ConfigurationProperty("id", IsRequired = false, IsKey = true)]
  public int Id
  {
    get { return (int)(this["id"]); }
    set { this["id"] = value; }
  }

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

  [ConfigurationProperty("products", IsRequired = false, IsKey = false, IsDefaultCollection = false)]
  public ProductCollection Products
   {
     get { return ((ProductCollection)(base["products"])); }
     set { base["products"] = value; }
   }
}

部门产品.cs

[ConfigurationCollection(typeof(Product), AddItemName = "product", CollectionType = ConfigurationElementCollectionType.BasicMapAlternate)]
public class ProductCollection: ConfigurationElementCollection
{
    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMapAlternate; }
    }

    protected override string ElementName
    {
        get { return string.Empty; }
    }

    protected override bool IsElementName(string elementName)
    {
        return (elementName == "product");
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return element;
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new Product();
    }

    protected override ConfigurationElement CreateNewElement(string elementName)
    {
        var product = new Product();
        return product;
    }

    public override bool IsReadOnly()
    {
        return false;
    }
}

部门产品.cs

public class Product : ConfigurationElement
{
  public Product()
  { }

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

  [ConfigurationProperty("price", IsRequired = false)]
  public decimal Price
  {
    get { return (decimal)(this["price"]); }
    set { price["name"] = value; }
  }

  [ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
  public KeyValueConfigurationCollection Items
  {
    get
    {
      var items = base[""] as KeyValueConfigurationCollection;
      return items;
    }
    set { base["items"] = value; }
  }
}

当我将上面显示的 XML 传递给 Departments.Deserialize 方法时,我收到以下错误:

When I pass the XML shown above to the Departments.Deserialize method, I receive the following error:

InvalidOperationException:您必须在 System.Configuration.ConfigurationLockCollection 上实现默认访问器,因为它继承自 ICollection.

如何将我共享的 XML 反序列化为共享的 C# 对象?

How do I deserialize the XML I shared into the C# objects shared?

推荐答案

我过去遇到过类似的问题.虽然我不知道如何处理 InvalidOperationException,但我设法通过直接将类标记为 IXmlSerializable

I had a similar issue in the past. While I couldn't figure out how to deal with the InvalidOperationException, I managed to get it working by directly tagging the class as IXmlSerializable

 [XmlRoot("departments")]
 public class Departments : ConfigurationSection, IXmlSerializable
 {
    //Your code here..

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

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

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

这篇关于无法在 C# 中反序列化 XML - InvalidOperationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆