2016-07-06 24 views
5

Esiste un modo per rimuovere le impostazioni da una classe JsonSerializer e reimplementarle in un nuovo JsonSerializer?Copia JsonSerializerSettings da JsonSerializer a nuovo JsonSerializer

Non sembrano esserci metodi per fare qualcosa del genere. Il meglio che ho trovato era un metodo privato per essere chiamato attraverso la riflessione, ApplySerializerSettings.

Sto provando a prendere il serializzatore dal metodo WriteJson e copiarlo in un nuovo serializzatore, modificandolo leggermente. Nello specifico voglio sostituire lo ContractResolver.

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

risposta

3

Sembra che il modo migliore sia copiare semplicemente tutte le impostazioni in un nuovo oggetto. Ce ne sono un sacco, quindi ecco un buon metodo di estensione con cui lavorare (a partire da 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; 
    } 
} 

È brutto, ma almeno devi solo scriverlo una volta. Fare attenzione, poiché le proprietà stesse non vengono copiate in profondità.

Risposta di seguito è instabile a seconda dell'implementazione, in particolare quando si tratta di risolvere un contratto. Mantenerlo nel caso in cui aiuti qualcuno.


Quindi, non riesco a copiare le impostazioni, ma ho trovato un buon lavoro che potrebbe voler essere considerato. È possibile semplicemente impostare le proprietà che si desidera modificare, in un contesto bloccato e quindi reimpostarle in un secondo momento.

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

Grazie, mi consente di dattilografare! Un po 'schifoso che dobbiamo fare questo, in realtà dovrebbe esserci qualcosa in Newtonsoft.Json – Tyson

Problemi correlati