2013-10-22 19 views
26

Uso di 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 di fare questo:Registrazione di un JsonConverter personalizzato a livello globale in Json.Net

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 presentare la mia convertitore personalizzato in ogni serializzazione/deserializzazione. Nel mio progetto ci sono molti casi in cui non posso farlo. Ad 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 per registrare il mio convertitore, utilizzando forse un membro static, in Json.Net, quindi non importa dove si verifica la serializzazione/deserializzazione, il mio convertitore è sempre presente?

risposta

46

Sì, questo è possibile utilizzando Json.Net 5.0.5 o successivo. Vedi JsonConvert.DefaultSettings.

JsonConvert.DefaultSettings =() => new JsonSerializerSettings 
{ 
    Converters = new List<JsonConverter> { new SomeConverter() } 
}; 

// Later on... 
string json = JsonConvert.SerializeObject(someObject); // this will use SomeConverter 

Se si utilizza API Web, è possibile impostare un convertitore a livello globale come questo, invece:

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

Grazie un milione, si ha reso il mio giorno :) – Mehran

+0

ottengo un errore in asp.net web api se faccio questo nel App_Start() evento . 'Metodo non trovato: 'Void Newtonsoft.Json.JsonConvert.set_DefaultSettings' –

+0

@DonnyV. probabilmente stai usando una versione precedente di JSON.NET - continua a compilarla a causa dei reindirizzamenti di versione aggiunti a web.config. – BrainSlugs83

13

Un altro approccio (che vince in priorità su quella @ Brian cita sopra) è a implementare un sistema di risoluzione del 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

+0

Hmm, 'JsonFormatter' non esiste più? – GregaMohorko

+0

Lo fa in WebAPI 2.x, a quale framework stai lavorando? Nucleo in pvc? Esiste un JsonInputFormatter e JsonOutputFormatter –

+0

.NET Framework 4.6.1. L'unica cosa che ho trovato è 'JsonConvert.DefaultSettings' che è di tipo' JsonSerializerSettings' e ha una proprietà 'ContractResolver', ma questo approccio non è diverso da quello di @Brian. – GregaMohorko

Problemi correlati