Posso distriggersre facoltativamente l’attributo JsonIgnore in fase di runtime?

Sto creando un file JSON con Newtonsoft.Json da un insieme 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.

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.

È comunque ansible ottenere il serializzatore per utilizzare facoltativamente gli attributi?

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

Non hai mostrato alcun codice, quindi farò solo un esempio. Diciamo che ho una class Foo come mostrato di seguito. Voglio le proprietà Id e Name nell’output di serializzazione, ma non sono assolutamente interessato a AlternateName e Color . Ho segnato quelli con [JsonIgnore] . Voglio che la descrizione appaia, ma a volte questo può richiedere molto tempo, quindi ho usato un JsonConverter personalizzato per limitarne la lunghezza. Voglio anche usare un nome di proprietà più breve per la descrizione, quindi l’ho marcato 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 serializzo un’istanza di cui 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 risultato:

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

Ora, diciamo che a volte voglio ottenere l’output JSON completo, ignorando le mie personalizzazioni. Posso usare un ContractResolver personalizzato per programmare “unapply” gli attributi della class. Ecco il codice per il resolver:

 class IgnoreJsonAttributesResolver : DefaultContractResolver { protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { IList 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 usare il resolver, lo aggiungo a JsonSerializerSettings e passo le impostazioni al serializer come questo:

 JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new IgnoreJsonAttributesResolver(); settings.Formatting = Formatting.Indented; string json = JsonConvert.SerializeObject(foo, settings); 

L’output ora include le proprietà ignorate e la descrizione non viene più troncata:

 { "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 completo qui: https://dotnetfiddle.net/WZpeWt

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 usarlo:

 Foo foo = new Foo { Id = 1, Name = "Thing 1", AlternateName = null, }; string json = JsonConvert.SerializeObject(foo);