2011-04-14 66 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

相关问题