Gibt es eine Möglichkeit, ich kann meinen eigenen benutzerdefinierten JsonConverter, der die Daten vor dem Schreiben der JSON ändert, die mit einer verschachtelten Eltern-Kind-Struktur funktioniert? Wann immer ich im Moment versuche, habe ich einen Fehler, der auf sich selbst bezieht. Ich habe versucht, nach Lösungen zu suchen, aber ich kann nichts finden, was passt.Benutzerdefinierte JsonConverter selbstreferenzierende Schleife
Ich habe eine einfache Lösung erstellt, um das Problem zu demonstrieren.
Ich habe das folgende Modell und Konverter
public class NestedModel
{
public int Id { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Custom { get; set; }
public List<SimpleModel> Children { get; set; }
}
public class NestedModelJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var nestedModel = value as NestedModel;
nestedModel.Custom = "Modified by Json Converter";
//This causes a self referencing loop error
serializer.Serialize(writer, value);
//This resolves the self referencing loop error, but it does not call my custom Json Converter for any of the Children, and instead uses the default serialization
//var jo = JObject.FromObject(value);
//jo.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
// Load JObject from stream
JObject jObject = JObject.Load(reader);
// Create target object based on JObject
NestedModel target = new NestedModel();
// Populate the object properties
StringWriter writer = new StringWriter();
serializer.Serialize(writer, jObject);
using (JsonTextReader newReader = new JsonTextReader(new StringReader(writer.ToString())))
{
newReader.Culture = reader.Culture;
newReader.DateParseHandling = reader.DateParseHandling;
newReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
newReader.FloatParseHandling = reader.FloatParseHandling;
serializer.Populate(newReader, target);
}
return target;
}
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return true; } }
public override bool CanConvert(Type objectType) { return typeof(NestedModel).IsAssignableFrom(objectType); }
}
und der Testcode zu verwenden, um es
string sourceJson = @"{
""Id"": 1,
""Forename"": ""John"",
""Surname"": ""Smith"",
""Children"":
[
{
""Id"": 2,
""Forename"": ""Joe"",
""Surname"": ""Bloggs"",
""Children"": null
}
]
}";
var settings = new JsonSerializerSettings()
{
Converters = new List<JsonConverter>()
{
new NestedModelJsonConverter()
},
Formatting = Formatting.Indented
};
var nestedModel = JsonConvert.DeserializeObject<NestedModel>(sourceJson, settings);
string outputJson = JsonConvert.SerializeObject(nestedModel, settings);
jedoch, wenn es die Json zu schreiben versucht, gibt es eine Schleife Fehler Selbstreferenzierung, vermutlich wenn es versucht, die Liste der Kinder zu verarbeiten. Ich kann diesen Fehler verhindern, indem ich ein JObject für die Konvertierung verwende, aber das verhindert, dass mein benutzerdefinierter Konverter für die untergeordneten Elemente verwendet wird. Ich möchte meine benutzerdefinierte WriteJson-Methode für jede Ebene dieser Struktur auslösen, damit ich einige Daten ändern kann, bevor ich sie schreibe.
Gibt es eine Möglichkeit, dies zu tun und den Fehler der selbstreferenzierenden Schleife zu umgehen?
Es gibt einige Optionen auf [JSON.Net wirft StackOverflowException bei Verwendung von '[JsonConvert]'] (https://stackoverflow.com/questions/29719509/json-net-throws-stackoverflowex ception-while-using-jsonconvert). – dbc
Auch verwandt: [Json.NET andere JSON-Struktur, basierend auf Enum-Wert] (https://StackOverflow.com/Questions/37896661/JSON-NET-Different-Json-Structure-Based-on-enum-Value?noredirect= 1 & lq = 1). – dbc