2011-04-14 44 views
4

讓您的火把準備好人!互聯網上的某個人表示.NET框架中存在一個錯誤! :-).NET XmlSerializer當兩個類具有同名屬性時的錯誤

考慮這個人爲的模型:

public class Barn 
{ 
    public Horse Horse { get; set; } 
    public Motorcycle Motorcycle { get; set; } 
} 

public class Horse 
{ 
    public Horse() 
    { 
     Rider = "Jim Craig"; 
    } 

    [XmlElement(IsNullable = true, Namespace = "abc")] 
    public string Rider { get; set; } 
} 

public class Motorcycle 
{ 
    public Motorcycle() 
    { 
     Rider = "Ghost"; 
    } 

    [XmlElement(IsNullable = false, Namespace = "abc")] 
    public string Rider { get; set; } 
} 

注意,共享相同的名稱和命名空間,但是其它沒有兩個Rider屬性。一個是XML可空,另一個不是。

下面是一些代碼到XML序列化和反序列化然後空騎:

// Create a Barn, with a Horse, with a null Rider 
Barn barnBefore = new Barn(); 
barnBefore.Horse = new Horse(); 
barnBefore.Horse.Rider = null; 

// Serialize and then deserialize the Barn 
XmlSerializer serializer = new XmlSerializer(typeof(Barn)); 
MemoryStream stream = new MemoryStream(); 
serializer.Serialize(stream, barnBefore); 
stream.Seek(0, SeekOrigin.Begin); 
Barn barnAfter = (Barn)serializer.Deserialize(stream); 

// Is the Horse's Rider still null? 
Console.WriteLine(barnAfter.Horse.Rider == null ? "null" : "not null"); 

HorseRider酒店IsNullable = true,所以其空值應通過串行化來維持。運行上面的代碼,輸出確實是null。到現在爲止還挺好。

現在,這裏是最有趣的部分:交換在BarnHorseMotorcycle屬性的順序,使Motorcycle是第一位的。

再次運行它,現在輸出爲非空。我勒個去?!

我對VS 2008測試,2010年

更多的樂趣,嘗試使兩個Rider性質不同的類型,例如一個string,另一個是int。那真的擰起來XmlSerializer

我對如何解決此問題不感興趣。這是微不足道的。我的問題是:這是一個錯誤,或者我誤解了什麼?

+0

我很好奇,想看看序列化的XML是什麼樣子 - 在原來的順序的屬性和你交換後他們。可能這是*序列化*而不是*反序列化的問題。* – 2011-04-14 04:55:26

+0

@Cory原文:''換行:''它正在序列化它好像'IsNullable'是錯誤的。 – 2011-04-14 05:03:16

+0

非常有趣 - 挖掘XML序列化來試圖解決這個問題也非常有效 - +1。 – Justin 2011-04-14 06:37:28

回答

3

那麼,在第一種情況下編寫的XML看起來有點像這樣:

<Barn> 
    <Horse> 
    <Rider xsi:nil="true" xmlns="abc" /> 
    </Horse> 
</Barn> 

但是在第二種情況下,XML是這樣的:

<Barn> 
    <Horse /> 
</Barn> 

因此,在第二種情況下基本上是在反序列化過程中發生的是這樣的:

Barn barn = new Barn(); 
barn.Hose = new Horse(); 

所以,因爲我們正在設置騎手在構造函數中默認爲「Jim Craig」。

有趣的是,只需更改Barn中元素的順序即可反轉行爲。爲了嘗試發現更多,我們可以使用ILSpySgen.exe進行挖掘 - 只需對我們的組件運行sgen並查看生成的程序集。

我們發現的是,在第一種情況中Write2_HorseWrite3_Motorcycle方法生成的代碼中有一行看起來像這樣:

​​

但是在第二種情況下,它看起來是這樣的:

base.WriteElementString("Rider", "abc", o.Rider); 

我不明白爲什麼改變這樣的元素的順序應該改變的Horse和這兩個序列化行爲的任何原因這樣的元素,所以簡而言之,這對我來說就像XML序列化程序集生成器中的一個錯誤。

你或許應該報告給微軟:-)

+0

生成的IL的冷卻分析。我在https://connect.microsoft.com/VisualStudio/feedback/details/661274提交了錯誤報告 – 2011-04-14 13:42:25

相關問題