2016-07-06 6 views
5

Gibt es eine Möglichkeit, die Einstellungen aus einer JsonSerializer Klasse zu nehmen und sie in einem neuen JsonSerializer neu zu implementieren?Kopieren von JsonSerializerSettings von JsonSerializer zu neuen JsonSerializer

Es scheint keine Methoden zu geben, um so etwas zu machen. Das Beste, was ich fand, war eine private Methode, die durch Reflexion aufgerufen werden konnte, ApplySerializerSettings.

Ich versuche, den Serializer von der WriteJson Methode zu nehmen und es in einen neuen Serialisierer zu kopieren und es ein wenig zu verbessern. Speziell möchte ich die ContractResolver ersetzen.

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 

Antwort

3

Scheint wie der beste Weg ist, nur alle Einstellungen in ein neues Objekt zu kopieren. Es gibt eine Menge von ihnen, also hier ist eine schöne Erweiterungsmethode (ab 8.0.3).

public static class JsonSerializerExtensions 
{ 
    public static JsonSerializer DeepCopy(this JsonSerializer serializer) 
    { 
    var copiedSerializer = new JsonSerializer 
    { 
     Context = serializer.Context, 
     Culture = serializer.Culture, 
     ContractResolver = serializer.ContractResolver, 
     ConstructorHandling = serializer.ConstructorHandling, 
     CheckAdditionalContent = serializer.CheckAdditionalContent, 
     DateFormatHandling = serializer.DateFormatHandling, 
     DateFormatString = serializer.DateFormatString, 
     DateParseHandling = serializer.DateParseHandling, 
     DateTimeZoneHandling = serializer.DateTimeZoneHandling, 
     DefaultValueHandling = serializer.DefaultValueHandling, 
     EqualityComparer = serializer.EqualityComparer, 
     FloatFormatHandling = serializer.FloatFormatHandling, 
     Formatting = serializer.Formatting, 
     FloatParseHandling = serializer.FloatParseHandling, 
     MaxDepth = serializer.MaxDepth, 
     MetadataPropertyHandling = serializer.MetadataPropertyHandling, 
     MissingMemberHandling = serializer.MissingMemberHandling, 
     NullValueHandling = serializer.NullValueHandling, 
     ObjectCreationHandling = serializer.ObjectCreationHandling, 
     PreserveReferencesHandling = serializer.PreserveReferencesHandling, 
     ReferenceResolver = serializer.ReferenceResolver, 
     ReferenceLoopHandling = serializer.ReferenceLoopHandling, 
     StringEscapeHandling = serializer.StringEscapeHandling, 
     TraceWriter = serializer.TraceWriter, 
     TypeNameHandling = serializer.TypeNameHandling, 
     SerializationBinder = serializer.SerializationBinder, 
     TypeNameAssemblyFormatHandling = serializer.TypeNameAssemblyFormatHandling 
    }; 
    foreach (var converter in serializer.Converters) 
    { 
     copiedSerializer.Converters.Add(converter); 
    } 
    return copiedSerializer; 
    } 
} 

Es ist hässlich, aber Sie müssen es nur einmal schreiben. Seien Sie vorsichtig, da die Eigenschaften selbst nicht tief kopiert werden.

Antwort unten ist flockig abhängig von der jeweiligen Implementierung, vor allem wenn es darum geht, einen Vertrag zu lösen. Halte es für den Fall ein, dass es jemandem hilft.

Also, ich kann die Einstellungen nicht ganz kopieren, aber ich fand eine gute Arbeit, die vielleicht in Betracht gezogen werden möchte. Sie können die Eigenschaften, die Sie ändern möchten, einfach in einem gesperrten Kontext festlegen und sie anschließend zurücksetzen.

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
{ 
    var thing = value as IThing; 

    if (thing == null) 
     throw new ArgumentException($"Writing Json failed because " + 
      "value was not a 'Thing' of type, {typeof(IThing).FullName}"); 

    JObject jsonThing; 
    //If your solution is multithreaded, 
    //and is using a shared serializer (which you probably are), 
    //you should lock the serializer so that it doesn't accidentally use 
    //the "CustomObjectResolver" 
    lock (serializer) 
    { 
     //Hold the original value(s) to reset later 
     var originalContractResolver = serializer.ContractResolver; 
     //Set custom value(s) 
     serializer.ContractResolver = new CustomObjectResolver(); 
     //Serialization with custom properties 
     jsonThing = JObject.FromObject(value, serializer); 
     //Reset original value(s) 
     serializer.ContractResolver = originalContractResolver; 
    } 

    //Finish serializing and write to writer. 
} 
+1

Danke, erspart mir das Tippen! Ein bisschen eklig, dass wir das tun müssen, aber es sollte wirklich etwas in Newtonsoft.Json eingebaut sein – Tyson