De-serialization issue when attribute is an array of objects
Opened this issue · 1 comments
Hi, given the following contracts
public class ResourceA
{
public string Id { get; set; }
public string Type { get; set; } = "A";
public ResourceB ResourceB { get; set; }
}
public class ResourceB
{
public string Id { get; set; }
public string Type { get; set; } = "B";
public ResourceC[] ResourceCs { get; set; }
}
public class ResourceC
{
public string Id { get; set; }
public string Type { get; set; } = "C";
public DateTimeOffset DateTimeOffset { get; set; }
}
and the following jsonapi instance
{
"data": {
"id": "8a45fc9f-8d08-49d1-9f21-43fe7d27b47f",
"type": "A",
"relationships": {
"resourceB": {
"data": {
"id": "20fa444b-38d7-481f-ac00-ef86b92fc8c0",
"type": "B"
}
}
}
},
"included": [
{
"id": "20fa444b-38d7-481f-ac00-ef86b92fc8c0",
"type": "B",
"attributes": {
"resourceCs": {
"data": []
}
}
}
]
}
what we get with v1.7.4 is an instance of ResourceA with a property of ResourceB with an array containing a default instance of ResourceC, with Id=null
, and DateTimeOffset=default(DateTimeOffset)
(instead of an empty array).
With version 1.3.1, the array was empty as expected.
I noticed that renaming attributes
to relationships
does work but in our case it comes from an external service..
In any case, is this a bug? Thanks
ResourceCs
is in the attributes so its treated as regular JSON serialization, it does not do any special handling of data property, its expecting your ResourceC object to have a data
property to deserialize into. It is the equivalent of JsonConvert.DeserializeObject<ResourceC>(@"{""Data"":[]}")
, which will return a default ResourceC (Id=null
, and DateTimeoOffset=defalt(DateTimeOffset)
)
The model that more accurately fits your JSON is
public class ResourceA
{
public string Id { get; set; }
public string Type { get; set; } = "A";
public ResourceB ResourceB { get; set; }
}
public class ResourceB
{
public string Id { get; set; }
public string Type { get; set; } = "B";
public ResourceCData ResourceCs { get; set; }
}
public class ResourceCData
{
public ResourceC[] Data { get; set; }
}
public class ResourceC
{
public string Id { get; set; }
public string Type { get; set; } = "C";
public DateTimeOffset DateTimeOffset { get; set; }
}
ResourceC
is not real Resource object, it is just an attribute that happens to have similar fields to a resource object.