【问题标题】:xml- Deserializexml-反序列化
【发布时间】:2009-12-10 19:41:07
【问题描述】:

我正在尝试反序列化我的类,通常是序列化的。

public class MyClass
{
   private List<Section> sections = new List<Section>();
   public List<Section> Sections
   {
        get
        {
          return this.sections;
        }
   }
}

public class Section1: Section
{
    public string MyProperty {get;set;}
}

public class Section2 : Section
{
    public string MyProperty2 {get;set;}
}

我序列化类 MyClass 没有错误,但是当我尝试反序列化它时,我收到一个类 MyClass 在 Section 中具有空属性(此属性为空)!

这是为什么,如何解决这个问题?

示例 xml:

<MyClass>
  <Sections>
     <Section1> 
       <MyProperty>foo1</MyProperty>
     </Section1>
     <Section1> 
       <MyProperty>foo2</MyProperty>
     </Section1>
     <Section2> 
       <MyProperty2>boo1</MyProperty2>
     </Section2>
  </Sections>
</MyClass>

序列化和反序列化代码:

用于序列化/反序列化的类:

public class ObjectSerializer
{
    private readonly XmlAttributeOverrides xmlAttributeOverrides = new XmlAttributeOverrides();

    public void XmlSerialize<T>(T value, TextWriter outStream)
    {
        Type type = typeof (T);
        object[] result = type.GetCustomAttributes(typeof (SerializableAttribute), true);
        if (result != null)
        {
            var serializer = new XmlSerializer(type, this.xmlAttributeOverrides);
            serializer.Serialize(outStream, value);
        }
    }

    public T XmlDeserialize<T>(string xml)
    {
        var textReader = new XmlTextReader(new StringReader(xml));
        var xmlSerializer = new XmlSerializer(typeof(T));

        var result = xmlSerializer.Deserialize(textReader);
        return (T)result;
    }


    public void ExportOverridesFrom<TAssemply, TBaseType, TObject>(
        Expression<Func<TObject, object>> propertySelector)
    {
        IEnumerable<Type> inheritedTypes = typeof (TAssemply).Assembly.GetTypes().Where(t => t.BaseType == typeof (TBaseType));
        var xmlAttributes = new XmlAttributes();
        foreach (Type type in inheritedTypes)
        {
            var xmlElementAttribute = new XmlElementAttribute {Type = type};
            xmlAttributes.XmlElements.Add(xmlElementAttribute);
        }
        PropertyInfo objectProperty = Reflect<TObject>.GetProperty(propertySelector);
        this.xmlAttributeOverrides.Add(typeof (TObject), objectProperty.Name, xmlAttributes);
    }
}

序列化:一切顺利!

var objectSerializer = new ObjectSerializer();
objectSerializer.ExportOverridesFrom<Section1, Section, MyClass>(p => p.Sections);
objectSerializer.XmlSerialize(myClass, resultStream);

反序列化:一切都很糟糕!

 xml - result serialization.
 var result = objectSerializer.XmlDeserialize<MyClass>(xml);

谢谢,奥克萨娜

【问题讨论】:

  • 请显示示例 XML。
  • 您是否需要“Section”属性的公共设置器以便 XmlSerializer 可以填充它?
  • 它没有解决问题,我尝试使用没有设置器的属性,但是这个类没有继承人,反序列化很顺利。 (当我添加一个属性不是继承人,而自己是基类,那么一切都很好)
  • 向我们展示您实例化 XmlSerializer 的代码
  • 嗯!这是一个有趣的帮手。

标签: c# serialization xml-serialization xml-deserialization


【解决方案1】:

您需要先将List&lt;Section&gt; sections 实例化为一个空列表,然后再使用它。

【讨论】:

  • 我实例化了一个属性,但结果是一样的
【解决方案2】:

您需要将私有部分成员的声明更改为:

private List<Section> sections = new List<Section>();

否则为null,无法赋值。

此外,您的 Sections 属性只有一个 Getter - 它需要一个 setter 否则永远不会设置:

public List<Section> Sections
{
    get
    {
      return this.sections;
    }

    set
    {
      this.sections = value;
    }

}

【讨论】:

  • 没有解决问题。不需要 Setter 当我添加属性 - (只有一个 setter)不是继承人,以及基类本身时,一切都很好。但我尝试添加一个 setter,没有任何改变。
【解决方案3】:
[DataContract]
[KnownType(typeof(Section1))]
[KnownType(typeof(Section2))]
public class Section
{ 

} 

尝试使用 DataContract 序列化器,您可以传入派生类型

序列化:

DataContractSerializer ser = new DataContractSerializer(typeof(Section),new Type[] { typeof(Section1),typeof(Section2)});
     ser.WriteObject(writer, sectionObj);
 writer.Close();

反序列化:

DataContractSerializer deser = new DataContractSerializer(typeof(Section),new Type[] { typeof(Section1),typeof(Section2)}););            
Section deserialisedSection = (Section)deser.ReadObject(reader, true);

【讨论】:

    【解决方案4】:

    我必须解决这个问题!

    何时创建序列化器,在构造函数中传递 xmlAttributeOverrides。 (即与序列化中的相同)。

     public T XmlDeserialize<T>(string xml)
        {
            var textReader = new XmlTextReader(new StringReader(xml));
            var xmlSerializer = new XmlSerializer(typeof(T), xmlAttributeOverrides); <--this
    
            var result = xmlSerializer.Deserialize(textReader);
            return (T)result;
        }
    

    成功了!

    【讨论】:

      猜你喜欢
      • 2012-03-04
      • 2011-03-03
      • 1970-01-01
      • 2011-05-12
      • 2011-06-24
      相关资源
      最近更新 更多