2016-05-22 23 views
7

Sto creando un file JSON con Newtonsoft.Json da un set di classi. Il file creato è molto grande, quindi ho creato JsonProperty per le proprietà per ridurre le dimensioni e aggiunto JsonIgnore e la formattazione personalizzata per alcuni tipi di dati.Posso disattivare facoltativamente l'attributo JsonIgnore in fase di runtime?

Il risultato è una riduzione da 24 MB a 1 MB, il che è ottimo; tuttavia, mi piacerebbe l'opzione per produrre la versione completa o la versione ridotta delle proprietà in fase di esecuzione.

È possibile comunque che il serializzatore utilizzi facoltativamente gli attributi?

+1

Forse mostrare un po 'di codice di come siete riusciti a personalizzare JSON.Net finora. –

risposta

16

Sì, questo può essere fatto utilizzando un codice personalizzato ContractResolver.

Non hai mostrato alcun codice, quindi farò solo un esempio. Diciamo che ho una classe Foo come mostrato di seguito. Voglio le proprietà Id e Name nell'output di serializzazione, ma non sono assolutamente interessato allo AlternateName e allo . Ho contrassegnato quelli con [JsonIgnore]. Voglio che la descrizione appaia, ma a volte questo può richiedere molto tempo, quindi ho usato un custom JsonConverter per limitarne la lunghezza. Voglio anche utilizzare un nome di proprietà più breve per la descrizione, quindi l'ho contrassegnato con [JsonProperty("Desc")].

class Foo 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    [JsonIgnore] 
    public string AlternateName { get; set; } 
    [JsonProperty("Desc")] 
    [JsonConverter(typeof(StringTruncatingConverter))] 
    public string Description { get; set; } 
    [JsonIgnore] 
    public string Color { get; set; } 
} 

Quando ho serializzare un'istanza di quanto sopra ...

Foo foo = new Foo 
{ 
    Id = 1, 
    Name = "Thing 1", 
    AlternateName = "The First Thing", 
    Description = "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.", 
    Color = "Yellow" 
}; 

string json = JsonConvert.SerializeObject(foo, Formatting.Indented); 

... ottengo questo output:

{ 
    "Id": 1, 
    "Name": "Thing 1", 
    "Desc": "This is some lengthy text describing Thing 1 " 
} 

Ora, diciamo che a volte mi voglio arrivare l'output JSON completo, ignorando le mie personalizzazioni. Posso usare un custom ContractResolver per programmare "unapply" gli attributi della classe. Ecco il codice per il resolver:

class IgnoreJsonAttributesResolver : DefaultContractResolver 
{ 
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     IList<JsonProperty> props = base.CreateProperties(type, memberSerialization); 
     foreach (var prop in props) 
     { 
      prop.Ignored = false; // Ignore [JsonIgnore] 
      prop.Converter = null; // Ignore [JsonConverter] 
      prop.PropertyName = prop.UnderlyingName; // restore original property name 
     } 
     return props; 
    } 
} 

Per utilizzare il resolver, lo aggiungo alla JsonSerializerSettings e passare le impostazioni per il serializzatore in questo modo:

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.ContractResolver = new IgnoreJsonAttributesResolver(); 
settings.Formatting = Formatting.Indented; 

string json = JsonConvert.SerializeObject(foo, settings); 

L'output include ora le proprietà ignorate, e la descrizione non viene troncato:

{ 
    "Id": 1, 
    "Name": "Thing 1", 
    "AlternateName": "The First Thing", 
    "Description": "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.", 
    "Color": "Yellow" 
} 

demo completa qui: https://dotnetfiddle.net/WZpeWt

+0

Risposta Brill Brian, funziona come un incantesimo, sai come disattivare l'attributo [JsonProperty ("ShortName")]? –

+0

Sì, aggiungi 'prop.PropertyName = prop.UnderlyingName;' all'interno del ciclo nel resolver. Questo farà sì che la proprietà usi il suo nome originale. –

+0

Ho aggiornato la mia risposta e il codice demo. –

1

Json ci supporta per ignorare le proprietà che non vogliono tornare. Esempio

class Foo 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] 
    public string AlternateName { get; set; }  
} 

Come si usa:

Foo foo = new Foo 
{ 
    Id = 1, 
    Name = "Thing 1", 
    AlternateName = null, 
}; 

string json = JsonConvert.SerializeObject(foo); 
+1

Questo non risponde alla domanda che è stata posta. –