【问题标题】:Doesn't deserialize one instance of an object不反序列化对象的一个​​实例
【发布时间】:2018-04-06 17:50:34
【问题描述】:

我有一个相当复杂的数据模型,它可以与 XML 进行序列化。我们都知道,当 C# 的 XmlSerializer 多次序列化对象的同一实例时,对象数据会重复。我遇到了一个对象实例未反序列化的问题。例如,假设我们有三个对象:A、B、C。假设 A 包含 B 的两个实例,B 包含 C 的列表。

A
->B
  ->List<C> -- This one deserializes
->B
  ->List<C> -- This one does not

当我反序列化对象 A 时,B 的第一个实例正确反序列化。但是,当我检查 B 的第二个实例时,List&lt;C&gt; 是空的。我对 XML 部分进行了差异比较,它们是相同的。

有谁知道为什么一个列表会反序列化而不是另一个?

更新

这是我能解决问题的最好方法。原始 XML 大约有 110,000 行长。

类:

[Serializable]
public class A
{
    public B instanceOne {get; set;}
    public B instanceTwo {get; set;}
}

[Serializable]
public class B : INotifyPropertyChanged
{
    private C _c;
    public ObservableCollection<C> C
    {
        get => _c;
        set
        {
            if(_c == value)
               return;
            _c = value;
            RaisePropertyChanged(nameof(C));
        }
   }
 //More Code
}

[Serializable, XmlRoot(ElementName = "MyC", Namespace = "MyNS")]
public class C
{
    public int value {get;set;}
}

XML 输出:

<?xml version="1.0"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <InstanceOne>
        <C>
          <Value xmlns="MyNS">10</Value>
        </C>
    </InstanceOne>
    <InstanceTwo>
        <C>
          <Value xmlns="MyNS">10</Value>
        </C>
    </InstanceTwo>
</A>

C#反序列化代码

XmlSerializer xml = new XmlSerializer(typeof(A));

using (FileStream fs = File.OpenRead(@"C:\a.xml"))
{
    var t = xml.Deserialize(fs);
}

【问题讨论】:

  • 对不起 - 你的意思是说类,而不是对象?你有两个不同的 B 类对象,还是同一个对象“B”两次?
  • 如果您显示实际的 XML、用于序列化/反序列化的代码以及相关类,将会有所帮助。
  • 我或多或少有一个对象,它有同一个对象的两个实例。我会共享 XML,但它有 113,000 行

标签: c# xml serialization xml-serialization


【解决方案1】:

列表应该具有适当的 XmlElement 属性以及名称。 和空列表(没有元素被跳过)。它适用于多个级别。 我转载了这个:

[Serializable]
public class A
{
    public A()
    {
        this.instanceOne = new B();
        this.instanceTwo = new B();
    }

    public B instanceOne { get; set; }
    public B instanceTwo { get; set; }
}

[Serializable]
public class B
{
    public B()
    {
        this._c = new C();
        this._c.value = 10;
    }

    private C _c;
}

[Serializable, XmlRoot(ElementName = "MyC", Namespace = "MyNS")]
public class C
{
    public int value { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var serializer = new XmlSerializer(typeof(A));
        var a = new A();
        try
        {
            var fs = new System.IO.FileStream("test.xml", System.IO.FileMode.Create);
            serializer.Serialize(fs, a);
            fs.Close();
            A d = (A)serializer.Deserialize(new System.IO.FileStream("test.xml", System.IO.FileMode.Open));
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

        Console.ReadLine();
    }
}

【讨论】:

  • 好吧,既然你使用的是可观察的集合和文件,你必须检查文件是否被锁定或者你有竞争条件。
  • Acimoic 我在哪里可以找到有关该主题的资源?
  • 在此处尝试类似的问题:stackoverflow.com/questions/12225853/… 并且还使用 lock() 是确保资源正在使用的方法。由于反序列化过程不是单线程执行中的问题,我认为您应该先模拟一个没有 ObsevableCollection 的测试用例,然后如果它有效,请深入挖掘 async、await 或 lock() 以使您的代码同步运行。
  • 一件奇怪的事是,一个集合反序列化而另一个不反序列化。
  • 我已经用列表替换了可观察的集合,我得到了相同的结果。
【解决方案2】:

我无法通过拨打XmlSerializer 解决手头的问题。我最终解析了文件,然后使用XmlReader 返回 XML 以填补特定缺失的空白。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多