我需要为新的 PoC 提供带有一些虚假数据的 Web API 服务。这个对象模型非常简单,有 2 个类,其中 class1 有一个嵌套数组 class2。所以我开始构建一个 FakeDataService,我只是在其中硬编码了一些数据。为简洁起见,我省略了很多属性,因此代码重点关注问题的本质:
public class Class1
{
public string Prop1 { get; set; }
public IEnumerable<Class2> Prop2 { get; set; }
public IEnumerable<string> Prop3 { get; set; }
}
public class Class2
{
public string Prop4 { get; set; }
}
public static class FakeDatabase
{
public static Class1 c1instance1 = new Class1 { Prop1 = "value1",
Prop2 = new Class2[] { c2instance1 },
Prop3 = new string[] { "value3" } };
public static Class2 c2instance1 = new Class2 { Prop4 = "Value4" };
public static Class1[] AllData = new Class1[] { c1instance1 };
}
所以,我的假数据库的“AllData”是一个 Class1 对象数组(本例中只有一个“数组”),Class1 对象有一个字符串属性(prop1)、一个 Class2 对象数组(prop2)和一个字符串属性数组 (prop3),而 Class2 对象只有一个字符串属性 (prop4)。
WebAPI 控制器是最基本的:
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<Class1> Get()
{
return FakeDatabase.AllData;
}
但是当我调用 Values 控制器时,结果是:
<ArrayOfClass1 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/FakeDataService.Models">
<Class1>
<Prop1>value1</Prop1>
<Prop2>
<Class2 i:nil="true"/>
</Prop2>
<Prop3 xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d3p1:string>value3</d3p1:string>
</Prop3>
</Class1>
</ArrayOfClass1>
注意 Class2 对象的序列化如何产生 i:nil=true
经过几个小时的搜索(我的示例数据比这里的这个简单示例大很多),我发现问题的根源在于嵌套对象数组被定义为静态实例。例如。将 FakeDatabase 的初始代码更改为:
public static class FakeDatabase
{
public static Class1 c1instance1 = new Class1 { Prop1 = "value1",
Prop2 = new Class2[] { new Class2 { Prop4 = "Value4" }},
Prop3 = new string[] { "value3" } };
public static Class1[] AllData = new Class1[] { c1instance1 };
}
现在调用 WebAPI 控制器给了我(正确):
<ArrayOfClass1 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/FakeDataService.Models">
<Class1>
<Prop1>value1</Prop1>
<Prop2>
<Class2>
<Prop4>Value4</Prop4>
</Class2>
</Prop2>
<Prop3 xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d3p1:string>value3</d3p1:string>
</Prop3>
</Class1>
</ArrayOfClass1>
所以唯一的区别是 Class2 对象的数组。这种行为的解释是什么?