Newtonsoft.json: Deserialization works on .net and mono but not .net core

Created on 1 Apr 2019  路  1Comment  路  Source: JamesNK/Newtonsoft.Json

Source/destination types

public class ValuesClass
{
    public IEnumerable<string> Values { get; set; } = Enumerable.Empty<string>();
}

Source/destination JSON

{"Values":[]}

Expected behavior

It shoud deserialize it and it does the expected behavior on full .net framework and mono.

Actual behavior

On all versions of .net core, I receive the following exception:

Newtonsoft.Json.JsonSerializationException: Cannot create and populate list type System.Linq.EmptyPartition`1[System.String]. Path 'Values', line 1, position 11.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(JsonReader reader, JsonArrayContract contract, Boolean& createdFromNonDefaultCreator)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
   at ConsoleApp2.Program.Main(String[] args) in C:\Users\dev\source\repos\ConsoleApp2\ConsoleApp2\Program.cs:line 14

Steps to reproduce

string valueJson = "{\"Values\":[]}";
ValuesClass valueObject = JsonConvert.DeserializeObject<ValuesClass>(valueJson);

Most helpful comment

I have hit this same problem and this appears to be due to a change with how netcore 3 handles casting the EmptyPartition<T>

The following fails with netcoreapp3.0 however succeeds in netcoreapp2.2
```c#
public static void Main(string[] args) {
var json = @"{""Values"":[]}";
var val = JsonConvert.DeserializeObject(json);
}
public class ValuesClass {
public IEnumerable Values { get; set; } = Enumerable.Empty();
}

The work around for this is to use something like

public IEnumerable Values { get; set; } = new List();
```

The exception thrown is https://github.com/JamesNK/Newtonsoft.Json/blob/cdf10151d507d497a3f9a71d36d544b199f73435/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs#L1209

Based on the issue in corefx https://github.com/dotnet/corefx/issues/32645 this appears to be because the EmptyPartition<T> will now no longer cast to IList<T>. I'm not sure if this is something that json.net needs to fix or not it's responsibility. Ideally it might need to explicitly handle the EmptyPartition<T> type and convert it to something like Array.Empty<T>() or something to that effect.

>All comments

I have hit this same problem and this appears to be due to a change with how netcore 3 handles casting the EmptyPartition<T>

The following fails with netcoreapp3.0 however succeeds in netcoreapp2.2
```c#
public static void Main(string[] args) {
var json = @"{""Values"":[]}";
var val = JsonConvert.DeserializeObject(json);
}
public class ValuesClass {
public IEnumerable Values { get; set; } = Enumerable.Empty();
}

The work around for this is to use something like

public IEnumerable Values { get; set; } = new List();
```

The exception thrown is https://github.com/JamesNK/Newtonsoft.Json/blob/cdf10151d507d497a3f9a71d36d544b199f73435/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs#L1209

Based on the issue in corefx https://github.com/dotnet/corefx/issues/32645 this appears to be because the EmptyPartition<T> will now no longer cast to IList<T>. I'm not sure if this is something that json.net needs to fix or not it's responsibility. Ideally it might need to explicitly handle the EmptyPartition<T> type and convert it to something like Array.Empty<T>() or something to that effect.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danebou picture danebou  路  18Comments

MuiBienCarlota picture MuiBienCarlota  路  14Comments

davidfowl picture davidfowl  路  49Comments

bytenik picture bytenik  路  11Comments

Phreak87 picture Phreak87  路  11Comments