【问题标题】:Why can't I deserialize a KnownType'd anyType?为什么我不能反序列化 KnownType'd anyType?
【发布时间】:2012-12-07 01:25:24
【问题描述】:

我正在尝试在 WCF 之外使用 DataContractSerializer 来序列化对象。本例中的对象继承自 CollectionBase 周围的旧通用包装器,例如

[KnownType(typeof(Foo)]
[CollectionDataContract]
class FooCollection : MyCollectionBase<Foo>

[KnownType(typeof(FooCollection)]
[KnownType(typeof(Foo)]
[CollectionDataContract]
class MyCollectionBase<T> : CollectionBase

[DataContract]
class Foo
{
    [DataMember]
    string Name;
    [DataMember]
    string Value;
}

当它被序列化时,我得到以下结构:

<FooCollection xmlns="http://schemas.datacontract.org/ ...>
  <anyType>
    <Name>...</Name>
    <Value>...</Value>
  </anyType>
</ArrayOfAnyType>

在反序列化时出现错误:

System.Runtime.Serialization.SerializationException : 命名空间 http://schemas.datacontract.org/2004/07/MyAssembly 中的元素 anyType 不能将子内容反序列化为对象。请使用 XmlNode[] 反序列化这种 XML 模式。

----> System.Xml.XmlException:预期来自命名空间“http://schemas.datacontract.org/2004/07/MyAssembly”的结束元素“anyType”。从命名空间“http://schemas.datacontract.org/2004/07/MyAssembly”中找到元素“名称”。第 1 行,位置 xxx。

谷歌搜索此错误显示许多人更改了他们的继承层次结构以使序列化工作,或者只是列出该方法的问题。我找不到任何使用 XmlNode[] 反序列化这种 XML 模式的示例。

所以我的问题是:

  1. 有没有办法让 DataContractSerializer 相信底层 ArrayList 中存储的类型是 Foo 类型?
  2. 如何实现 XmlNode[] 解决方法?
  3. 是使用不受非泛型集合支持的泛型集合的唯一解决方案吗?

【问题讨论】:

    标签: c# .net arraylist datacontractserializer


    【解决方案1】:

    鉴于您上面的代码,我使用以下代码进行序列化和反序列化:

            var serializer = new DataContractSerializer(typeof(FooCollection));
            IList collection = new FooCollection();
            var foo = new Foo();
            foo.Name = "TestName";
            foo.Value = "Test value";
            collection.Add(foo);
            StringBuilder sb = new StringBuilder();
            StringWriter writer = new StringWriter(sb);
            XmlTextWriter xmlWriter = new XmlTextWriter(writer);
    
            serializer.WriteObject(xmlWriter, collection);
            Console.WriteLine(sb.ToString());
            var serialized = sb.ToString();
    
            var reader = new StringReader(serialized);
            var xmlReader = new XmlTextReader(reader);
            var deserialized = serializer.ReadObject(xmlReader);
    
            return;
    

    使用 .Net 4.0 和 Visual Studio 2010 没有任何问题。 如果您想更改元素的名称,使其不是“anyType”,您可以将 FooCollection 类的 CollectionDataContract 属性更改为:

        [CollectionDataContract(ItemName="Foo")]
    

    【讨论】:

      【解决方案2】:

      我找到了问题的原因,在我原来的问题中没有显示:MyCollectionBase 实现了 ISerializable。

      DataContractSerializer 将在使用任何属性之前使用 ISerializable 实现。它也无法从 ISerializable 中推断出合同,因此没有针对 anyType 反序列化的解决方法。

      这就是 KnownTypeAttribute 不起作用的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多