According to Json.Net documentation all
IEnumerable
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; }
}
[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": []
}
The default automatic behaviour of Json.Net, when deserializing into an IEnumerable
or IList
field, is to create a List
instance. If you assign an Array
instance, then the only way to restore your object to it original instance state is for Json.Net to add the $type
meta data, which is what you are seeing. i.e. there are many ways to deserialize into an IEnumerable
field.
By using a List<string>
instance:
var myEvent = new MyClass
{
Values = new List<string>(),
};
with:
public class MyClass
{
public IEnumerable<string> Values { get; set; }
}
results in (when serialized):
{"Values":["hello"]}
Also, if you use an explicit constructable type or use the default List, then Json.Net will use that and omit $type
;
For instance:
string[] Values { get; set; } = new string[0]; // not needed
IEnumerable<string> Values { get; set; } = new string[0]; //$type needed
IEnumerable<string> Values { get; set; } = new Stack<string>(); //$type needed
IEnumerable<string> Values { get; set; } = new List<string>; // not needed
List<string> Values { get; set; } = new List<string>; // not needed
ObservableCollection<string> Values { get; set; } =
new ObservableCollection<string>(); // not needed