Согласно Json.Net documentation все типы IEnumerable
должны быть сериализованы как массив json.Сериализация Json.Net IEnumerable с типомNameHandling = авто
Поэтому я ожидаю следующий класс:
public class MyClass
{
public IEnumerable<string> Values { get; set; }
}
сериализовать как:
{
"Values": []
}
Проблема заключается в том, что, когда я использую TypeNameHandling=Auto
я получаю:
{
"Values": {
"$type": "System.String[], mscorlib",
"$values": []
}
}
мне нужно TypeNameHandling=Auto
для других объектов, но я ожидаю, что IEnumerable
использовать defa сверхсериализация. Другие типы (например, 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', вы получите такое же поведение. Как я уже указывал, поведение десериализации по умолчанию заключается в создании экземпляра 'List' для полей интерфейса Enumerable и' IList'. Если вы укажете явный тип объекта, он будет использовать это вместо этого; но существует множество способов создания экземпляра 'IEnumerable'. единственный способ узнать, какой именно экземпляр вы использовали, если вы идете против значения по умолчанию, заключается в добавлении метаданных '$ type' –