2008-09-13 56 views
298

使用C#.NET 2.0,我有一個組合數據類,其上有[Serializable]屬性。我創建一個XMLSerializer類,並傳遞一個到構造函數:XmlSerializer - 反映類型時出現錯誤

XmlSerializer serializer = new XmlSerializer(typeof(DataClass)); 

我得到一個異常的說法:

有反映類型錯誤。

數據類中還有另一個複合對象。這是否也需要具有[Serializable]屬性,或者將它放在頂層對象上,是否將其遞歸應用於所有對象?

回答

379

看看你正在得到的內部異常。它會告訴你哪個字段/屬性有序列化的麻煩。

通過使用[XmlIgnore]屬性對它們進行修飾,可以從xml序列化中排除字段/屬性。

我不認爲XmlSerializer使用[Serializable]屬性,所以我懷疑這是問題所在。

+11

我的對象有一個Uri字段,這引起了這個異常; Uri類沒有無參數的構造函數。謝謝你的提示。 – ford 2011-10-28 21:45:16

+7

在谷歌搜索中遇到了這個問題 - 當我需要成爲List時,我的特殊問題是在我的「被序列化」類中擁有一個屬性爲「IList」。 – 2012-10-08 13:06:59

+7

如何看待「內部例外」? – David 2012-12-17 03:47:59

0

另請注意,您不能序列化用戶界面控件,並且要傳遞到剪貼板的任何對象都必須是可序列化的,否則不能傳遞給其他進程。

2

我也認爲Serializable屬性必須是對該對象,但除非我是一個完整的noob(我正處於深夜編碼會話中),以下作品來自SnippetCompiler

using System; 
using System.IO; 
using System.Xml; 
using System.Collections.Generic; 
using System.Xml.Serialization; 

public class Inner 
{ 
    private string _AnotherStringProperty; 
    public string AnotherStringProperty 
    { 
     get { return _AnotherStringProperty; } 
     set { _AnotherStringProperty = value; } 
    } 
} 

public class DataClass 
{ 
    private string _StringProperty; 
    public string StringProperty 
    { 
     get { return _StringProperty; } 
     set{ _StringProperty = value; } 
    } 

    private Inner _InnerObject; 
    public Inner InnerObject 
    { 
     get { return _InnerObject; } 
     set { _InnerObject = value; } 
    } 
} 

public class MyClass 
{ 

    public static void Main() 
    { 
     try 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(DataClass)); 
      TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml"); 
      DataClass clazz = new DataClass(); 
      Inner inner = new Inner(); 
      inner.AnotherStringProperty = "Foo2"; 
      clazz.InnerObject = inner; 
      clazz.StringProperty = "foo"; 
      serializer.Serialize(writer, clazz); 
     } 
     finally 
     { 
      Console.Write("Press any key to continue..."); 
      Console.ReadKey(); 
     } 
    } 

} 

我會想象XmlSerializer使用公共屬性的反射。

105

請記住,序列化類必須具有默認(即無參數)構造函數。如果你根本沒有構造函數,那很好;但是如果你有一個帶參數的構造函數,你還需要添加默認的參數。

4

我發現.Net 2.0中的Dictionary類不能使用XML進行序列化,但在使用二進制序列化時序列化良好。

我發現了一個圍繞here的工作。

4

如果您需要處理特定的屬性(即字典,或任何一類),您可以實現IXmlSerialiable接口,這將讓你更多的自由在更詳細的編碼成本。

public class NetService : IXmlSerializable 
{ 
    #region Data 

     public string Identifier = String.Empty; 

     public string Name = String.Empty; 

     public IPAddress Address = IPAddress.None; 
     public int Port = 7777; 

    #endregion 

    #region IXmlSerializable Implementation 

     public XmlSchema GetSchema() { return (null); } 

     public void ReadXml(XmlReader reader) 
     { 
      // Attributes 
      Identifier = reader[XML_IDENTIFIER]; 
      if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false) 
      throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT); 
      if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false) 
      throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR); 
     } 

     public void WriteXml(XmlWriter writer) 
     { 
      // Attributes 
      writer.WriteAttributeString(XML_IDENTIFIER, Identifier); 
      writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString()); 
      writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString()); 
     } 

     private const string XML_IDENTIFIER = "Id"; 

     private const string XML_NETWORK_ADDR = "Address"; 

     private const string XML_NETWORK_PORT = "Port"; 

    #endregion 
} 

有一個有趣的article,其表現出優雅的方式來實現複雜的方式來「擴展」 XmlSerializer的。


文章說:

IXmlSerializable的覆蓋的正式文件,但文件指出它不打算供公衆使用,並提供超出任何信息。這表明開發團隊希望保留修改,禁用或甚至完全刪除這個可擴展性的權利。但是,只要你願意接受這種不確定性,並在將來處理可能的變化,就沒有任何理由不能利用它。

因此,我建議實施你自己的IXmlSerializable類,以避免太複雜的實現。

...使用反射來實現我們自定義的XmlSerializer類可能很簡單。

3

我最近在添加新屬性時在Web引用partial類中得到了這個。自動生成的類正在添加以下屬性。

[System.Xml.Serialization.XmlElementAttribute(Order = XX)] 

我需要添加一個類似的屬性與自動生成的序列中的順序一個比過去更高,這個固定爲我。

20

我有一個類似的問題,事實證明,序列化程序無法區分我有同名的兩個類(一個是另一個的子類)。內部異常如下所示:

'類型BaseNamespace.Class1'和'BaseNamespace.SubNamespace.Class1'都使用名稱空間''中的XML類型名稱'Class1'。使用XML屬性爲類型指定唯一的XML名稱和/或名稱空間。

其中BaseNamespace.SubNamespace.Class1是BaseNamespace.Class1的子類。

我需要做什麼是一個屬性添加到其中的一個類(我加入到基類):

[XmlType("BaseNamespace.Class1")] 

注意:如果你擁有類多層你需要的屬性添加到他們也是如此。

1

我剛剛得到相同的錯誤,發現IEnumerable<SomeClass>類型的屬性是問題。看來IEnumerable不能被直接序列化。

1

我有一種情況,我們訂的是一排

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")] 

....一些代碼兩個元素一樣...

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")] 

當我改變了代碼遞增對於班級中每個新物業的訂單,該錯誤消失。

4

最常見的原因由我:

- the object being serialized has no parameterless constructor 
- the object contains Dictionary 
- the object has some public Interface members 
0

[System.Xml.Serialization.XmlElementAttribute( 「strFieldName」,表= System.Xml.Schema.XmlSchemaForm.Unqualified)]

//或

[XmlIgnore] 的String [] {strFielsName獲得;設置;}

0

我有同樣的問題,在我的情況下,對象有一個ReadOnlyCollection。集合必須實現Add方法才能被序列化。

相關問題