根据Json.Net documentation所有IEnumerable
类型应该序列化为json数组。Json.Net IEnumerable的序列化与TypeNameHandling = auto
因此,我希望下面的类:
public class MyClass
{
public IEnumerable<string> Values { get; set; }
}
被序列为:
{
"Values": []
}
的问题是,当我使用TypeNameHandling=Auto
我得到:
{
"Values": {
"$type": "System.String[], mscorlib",
"$values": []
}
}
我需要TypeNameHandling=Auto
其他物业,但我期望IEnumerable
你默认序列化。其他类型(例如IList
)按预期工作。
这是一个错误还是我错过了什么?
[Test]
public void Newtonsoft_serialize_list_and_enumerable()
{
var target = new Newtonsoft.Json.JsonSerializer
{
TypeNameHandling = TypeNameHandling.Auto
};
var myEvent = new MyClass
{
Values = new string[0]
};
var builder = new StringWriter();
target.Serialize(builder, myEvent);
var json = JObject.Parse(builder.ToString());
Assert.AreEqual(JTokenType.Array, json["Values"].Type);
}
public class MyClass
{
public IEnumerable<string> Values { get; set; }
}
我使用Newtonsoft 7.0.1:
这里的全部代码重现该问题。
UPDATE: 这里使用更多类型的另一项测试:
[Test]
public void Newtonsoft_serialize_list_and_enumerable()
{
var target = new Newtonsoft.Json.JsonSerializer
{
TypeNameHandling = TypeNameHandling.Auto
};
var myEvent = new MyClass
{
Values1 = new string[0],
Values2 = new List<string>(),
Values3 = new string[0],
Values4 = new List<string>(),
Values5 = new string[0]
};
var builder = new StringWriter();
target.Serialize(builder, myEvent);
var json = builder.ToString();
}
public class MyClass
{
public IEnumerable<string> Values1 { get; set; }
public IEnumerable<string> Values2 { get; set; }
public IList<string> Values3 { get; set; }
public IList<string> Values4 { get; set; }
public string[] Values5 { get; set; }
}
这是结果:
{
"Values1": {
"$type": "System.String[], mscorlib",
"$values": []
},
"Values2": [],
"Values3": {
"$type": "System.String[], mscorlib",
"$values": []
},
"Values4": [],
"Values5": []
}
同样,我不明白为什么我得到这取决于不同的结果组合。
谢谢,我可能会使用这个解决方案。但我认为这是一个错误,因为所有类型的行为都应该是相同的,而如果我使用'List'或'array',我会得到不同的结果。 –
对我而言,这是不正确的。如果您将'new string [0]'设置为'IList'字段,则您将获得相同的行为。正如我所指出的,默认的反序列化行为是为Enumerable和IList接口字段创建一个List实例。如果你指定一个明确的对象类型,它将使用它,但有很多方法来实例化一个'IEnumerable'。如果违背默认值,唯一的方法就是添加'$ type'元数据 –