2016-09-07 3 views
0

Ich habe eine C# -Anwendung, die JSON verwendet. Es gibt einen Fehler und es ist ein bisschen kompliziert, also werde ich ein Beispiel geben. Wenn wir diese Klasse:Benutzerdefinierte Json Converter, der Standardkonverter verwendet

public class FatherObj 
{ 
    public SonObj Son {get; set;} 
} 

public class SonObj 
{ 
    public List<GrandChildObj> GrandChildren {get; set;} 
} 

dann, wenn sie mit JSON-Objekt FatherObj die Liste der Enkelkinder im Objekt Deserialisieren SonObj dupliziert wird. Ich reparierte sie durch über die Deklaration der Liste hinzugefügt haben den folgenden Code:

[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] 

Allerdings, wenn ich es in die JSON Serialisierung Einstellung der gesamten Anwendung Hinzufügen versucht, es Probleme verursacht. Also habe ich beschlossen, einen JsonConverter zu erstellen, der nur für List-Objekte gilt und beim Deserialisieren die Distinct-Methode aufruft, bevor er zurückkehrt. Aber JsonConverter ist eine abstrakte Klasse, so dass Sie bei der Implementierung ihrer Methoden keine Basismethoden (wie sie auch abstrakt sind) aufrufen können. Wie rufe ich die Standardkonvertereinstellungen auf? Ich möchte neben dem distinct keine andere Konvertierung erstellen.

+0

Will 'CollectionClearingContractResolver' von [dieser Frage] (https://stackoverflow.com/questions/35482896/clear-collections-before-adding-items-when- Populating-Existing-Objects) erfüllen Ihre Bedürfnisse? – dbc

+0

Es gibt keinen Platz im Code, der "PopulateObject" aufruft. Funktioniert das immer noch nur zum Deserialisieren? –

+0

Es sollte tun. Sie können 'JsonSerializerSettings.ContractResolver' setzen und dann die Einstellungen an' DeserializeObject' übergeben. Siehe http://www.newtonsoft.com/json/help/html/contractresolver.htm. Aber wenn es nicht funktioniert oder andere Probleme auftreten, können Sie den C# Code teilen, der nicht funktioniert? – dbc

Antwort

1

Ok, also nach einer Weile mit Hilfe von Benutzer DBC des Suchens - ich seine Antwort nahm aber von einem anderen Link: How to apply ObjectCreationHandling.Replace to selected properties when deserializing JSON?

Die Lösung, die er in den Link gepostet: Erstellen eines benutzerdefinierten ContractResolver (dass erbt von DefaultContractResolver) mit dem folgenden Code:

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
{ 
    var jsonProperty = base.CreateProperty(member, memberSerialization); 
    if (jsonProperty.ObjectCreationHandling == null && jsonProperty.PropertyType.GetListType() != null) 
     jsonProperty.ObjectCreationHandling = ObjectCreationHandling.Replace; 
    return jsonProperty; 
} 

public static class TypeExtensions 
{ 
    public static Type GetListType(this Type type) 
    { 
     while (type != null) 
     { 
      if (type.IsGenericType) 
      { 
       var genType = type.GetGenericTypeDefinition(); 
       if (genType == typeof(List<>)) 
        return type.GetGenericArguments()[0]; 
      } 
      type = type.BaseType; 
     } 
     return null; 
    } 
}