Hallo
We have a complex nested model which consist of numerous parents and child. eg..
MESSAGE --> HEAD ---> WAVE --> ODH[ARRAY] --> ODL[ARRAY]
--> SHUFF[ARRAY]
etc, and more nested.
The issue is I want to be able to add the parameters of WAVE into the ODH model. but it complains about circular reference when posting to the model.
The error when posting message below.. (I don't want to use json Preserve because is creates $ref and $id which is visible in the json string.
I have also tried adding the below code to the program.cs file with the converter class..
We have a complex nested model which consist of numerous parents and child. eg..
MESSAGE --> HEAD ---> WAVE --> ODH[ARRAY] --> ODL[ARRAY]
--> SHUFF[ARRAY]
etc, and more nested.
The issue is I want to be able to add the parameters of WAVE into the ODH model. but it complains about circular reference when posting to the model.
Model example:
public class WAVE_WCSWAVE : WAVE
{
public int ODHId { get; set; }
public List<ODH_WCSWAVE>? ODH { get; set; }
}
public class INVDET_WCSWAVE : INVDET
{
public SKUCON_WCSWAVE? SKUCON { get; set; }
}
public class SKUCON_WCSWAVE : SKUCON
{
}
public class ODH_WCSWAVE : ODH
{
//[Column("WAVE_WCSWAVEId")]
//public int WaveId { get; set; }
//public WAVE_WCSWAVE? Wave { get; set; }
public List<ODL_WCSWAVE>? ODL { get; set; }
public ODHUDF_WCSWAVE? ODHUDF { get; set; }
}
The error when posting message below.. (I don't want to use json Preserve because is creates $ref and $id which is visible in the json string.
Error Message:
System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.DSV_WCSWAVE0430.HEAD.WAVE.ODH.Wave.ODH.Wave.ODH.Wave.ODH.Wave.ODH.Wave.ODH.Wave.ODH.Wave.ODH.Wave.ODH.Wave.ODH.
at System.Text.Json.ThrowHelper.ThrowJsonException_SerializerCycleDetected(Int32 maxDepth)
I have also tried adding the below code to the program.cs file with the converter class..
Configuration:
builder.Services.Configure<JsonSerializerOptions>(options =>
{
options.ReferenceHandler = ReferenceHandler.Preserve;
options.Converters.Add(new ObjectCycleConverter<DSVWCSWAVE0430_Inbound>());
options.Converters.Add(new ObjectCycleConverter<HEAD_WCSWAVE>());
options.Converters.Add(new ObjectCycleConverter<WAVE_WCSWAVE>());
options.Converters.Add(new ObjectCycleConverter<ODH_WCSWAVE>());
options.Converters.Add(new ObjectCycleConverter<ODL_WCSWAVE>());
});
Converter:
public class ObjectCycleConverter<T> : JsonConverter<T>
{
private readonly Dictionary<string, T> _referenceCache = new Dictionary<string, T>();
public override bool CanConvert(Type typeToConvert)
{
return typeof(T).IsAssignableFrom(typeToConvert);
}
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<T>(ref reader, options);
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var referenceId = GetReferenceId(value);
if (!string.IsNullOrEmpty(referenceId))
{
writer.WriteStringValue(referenceId);
return;
}
referenceId = Guid.NewGuid().ToString();
_referenceCache.Add(referenceId, value);
writer.WriteStartObject();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
writer.WritePropertyName(property.Name);
var propertyValue = property.GetValue(value);
JsonSerializer.Serialize(writer, propertyValue, property.PropertyType, options);
}
writer.WriteEndObject();
}
private string GetReferenceId(T value)
{
foreach (var kvp in _referenceCache)
{
if (ReferenceEquals(kvp.Value, value))
{
return kvp.Key;
}
}
return null;
}
}