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.
}
Grazie, mi consente di dattilografare! Un po 'schifoso che dobbiamo fare questo, in realtà dovrebbe esserci qualcosa in Newtonsoft.Json – Tyson