Registrazione di un JsonConverter personalizzato a livello globale in Json.Net

Usando Json.Net , ho delle proprietà nei miei oggetti che richiedono particolare attenzione per serializzarle / deserializzarle. Facendo un discendente di JsonConverter , sono riuscito a farlo con successo. Questo è il modo comune per farlo:

 public class SomeConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { ... } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { ... } public override bool CanConvert(Type objectType) { ... } } class SomeClass { [JsonProperty, JsonConverter(typeof(SomeConverter))] public SomeType SomeProperty; } //Later on, in code somewhere SomeClass SomeObject = new SomeClass(); string json = JsonConvert.SerializeObject(SomeObject, new SomeConverter()); 

Il mio problema con questo codice è che ho bisogno di introdurre il mio convertitore personalizzato in ogni serializzazione / deserializzazione. Nel mio progetto ci sono molti casi in cui non posso farlo. Per esempio, sto usando altri progetti esterni che fanno uso di Json.Net e lavoreranno sulle mie istanze SomeClass . Ma dal momento che non voglio o non posso apportare modifiche nel loro codice, non ho modo di introdurre il mio convertitore.

C’è un modo in cui posso registrare il mio convertitore, usando forse qualche membro static , in Json.Net, quindi non importa dove avviene la serializzazione / deserializzazione, il mio convertitore è sempre presente?

Sì, questo è ansible usando Json.Net 5.0.5 o successivo. Vedi JsonConvert.DefaultSettings .

 JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Converters = new List { new SomeConverter() } }; // Later on... string json = JsonConvert.SerializeObject(someObject); // this will use SomeConverter 

Se si utilizza l’API Web, è ansible impostare un convertitore globalmente come questo, invece:

 var config = GlobalConfiguration.Configuration; var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings; jsonSettings.Converters.Add(new SomeConverter()); 

Un altro approccio (che vince in via prioritaria rispetto a quello sopra menzionato da @Brian) è l’implementazione di un risolutore di contratto personalizzato

 JsonFormatter.SerializerSettings.ContractResolver = new CustomContractResolver(); 

E l’implementazione è piuttosto semplice

 public class CustomContractResolver : DefaultContractResolver { private static readonly JsonConverter _converter = new MyCustomConverter(); private static Type _type = typeof (MyCustomType); protected override JsonConverter ResolveContractConverter(Type objectType) { if (objectType == null || !_type.IsAssignableFrom(objectType)) // alternatively _type == objectType { return base.ResolveContractConverter(objectType); } return _converter; } } 

Entrambi i metodi sono validi, questo è solo un martello più grande