codecutout / JsonApiSerializer

JsonApiSerializer supports configurationless serializing and deserializing objects into the json:api format (http://jsonapi.org).
MIT License
113 stars 46 forks source link

Deserialization doesn't work when type has a constructor #125

Open DumpsterDoofus opened 4 years ago

DumpsterDoofus commented 4 years ago

Minimal working example:

public static void Main()
{
    var json =
        "{ \"data\": [ { \"type\": \"articles\", \"id\": \"1\", \"attributes\": { \"title\": \"JSON API paints my bikeshed!\" } } ] }";
    JsonConvert.DeserializeObject<Article[]>(json, new JsonApiSerializerSettings());
}

public class Article
{
    public string Id { get; set; }

    public string Title { get; set; }

    public Article(string id, string title)
    {
        Id = id;
        Title = title;
    }
}

Deserialization throws the following exception:

Unhandled exception. Newtonsoft.Json.JsonSerializationException: Could not create an instance of type Test.Program+Article.
   at JsonApiSerializer.JsonConverters.ResourceObjectConverter.CreateObject(Type objectType, String jsonapiType, JsonSerializer serializer)
   at JsonApiSerializer.JsonConverters.ResourceObjectConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at JsonApiSerializer.JsonConverters.ResourceObjectListConverter.<>c__DisplayClass4_0.<ReadJson>b__0(Object x)
   at System.Linq.Enumerable.SelectEnumerableIterator`2.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at JsonApiSerializer.Util.ListUtil.CreateList(Type listType, IEnumerable`1 elements)
   at JsonApiSerializer.JsonConverters.ResourceObjectListConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
   at JsonApiSerializer.JsonConverters.DocumentRootConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at JsonApiSerializer.JsonConverters.DocumentRootConverter.ResolveAsRootData(JsonReader reader, Type objectType, JsonSerializer serializer)
   at JsonApiSerializer.JsonConverters.ResourceObjectListConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, 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 Test.Program.Main() in E:\Software\My Software\Test\Test\Program.cs:line 12

An exception is not thrown if the constructor is commented out. Unfortunately, removing constructors is not an option for my use case.

Vanilla Newtonsoft.Json supports deserializing into types with constructors. Does this library override the normal deserialization in such a way that we lose this feature?