I was trying to follow the Preserving Object References example for my application, but it doesn't seem to work in my test case.
There are three minimal classes:
- Firm (top)
- Employee
- ClientGroup (references Employee in Advisors collection property)
The Employee is deserialized successfully, but the $ref references are ignored in the Advisors collection and an extra blank object is created in its place.
I searched all over for any information on the "Could not find member '$ref'" trace message, but haven't found anything. This question Deserializing $ref and $id suggested adding MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
to the settings. This removed the trace warning but the reference was still replaced by a new blank Employee.
Any help would be most appreciated.
Json:
[
{
"$id": "1",
"Employees": [
{
"$id": "2",
"FirstName": "Billy",
"LastName": "Thornton",
"MiddleName": "Bob"
}
],
"ClientGroups": [
{
"$id": "3",
"Name": "Group A",
"Advisors": [
{
"$ref": "2"
}
]
}
],
"FullName": "The Firm"
}
]
The deserialization code is:
// converters create objects for my ORM (XPO)
var converters = new JsonConverter[]
{
new jsonConverter<Firm>(objectSpace),
new jsonConverter<Employee>(objectSpace),
new jsonConverter<ClientGroup>(objectSpace)
};
var settings = new JsonSerializerSettings() {
Converters = converters,
TraceWriter = traceWriter,
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
var Firms = JsonConvert.DeserializeObject<List<Firm>>(
File.ReadAllText($"{seedPathPrefix}{firmSeed}", ASCII),
settings);
Trace.WriteLine($"Trace:\n{traceWriter}");
// required by ORM for object creation
private class jsonConverter<T> : CustomCreationConverter<T> {
public jsonConverter(IObjectSpace objectSpace) { this.objectSpace = objectSpace; }
private IObjectSpace objectSpace;
public override T Create(Type objectType) {
if (objectType.IsEnum) return default;
return objectSpace.CreateObject<T>();
}
}