Comment ignorer une propriété dans la classe si null, en utilisant json.net

J'utilise Json.NET {[7] } pour sérialiser une classe en JSON.

J'ai la classe comme ceci:

class Test1
{
    [JsonProperty("id")]
    public string ID { get; set; }
    [JsonProperty("label")]
    public string Label { get; set; }
    [JsonProperty("url")]
    public string URL { get; set; }
    [JsonProperty("item")]
    public List<Test2> Test2List { get; set; }
}

Je veux ajouter un JsonIgnore() attribut Test2List bien que lorsque Test2List est null. Si ce n'est pas null, je veux l'inclure dans mon json.

363
demandé sur Vito Gentile 2011-06-28 18:14:55

10 réponses

Selon James Newton King: si vous créez le sérialiseur vous-même plutôt que D'utiliser JavaScriptConvert, il y a un NullValueHandling propriété que vous pouvez définir pour ignorer.

Voici un exemple:

JsonSerializer _jsonWriter = new JsonSerializer {
                                 NullValueHandling = NullValueHandling.Ignore
                             };

Alternativement, comme suggéré par @amit

JsonConvert.SerializeObject(myObject, 
                            Newtonsoft.Json.Formatting.None, 
                            new JsonSerializerSettings { 
                                NullValueHandling = NullValueHandling.Ignore
                            });
476
répondu Mrchief 2016-01-30 20:51:06

Une solution alternative utilisant l'attribut JsonProperty:

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
//or
[JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)]

Comme dans ce document en ligne.

625
répondu sirthomas 2014-09-10 04:19:54

Similaire à la réponse de @sirthomas, JSON.NET respecte également la propriété EmitDefaultValue sur DataMemberAttribute:

[DataMember(Name="property_name", EmitDefaultValue=false)]

Cela peut être souhaitable si vous utilisez déjà [DataContract] et [DataMember] dans votre type de modèle et que vous ne souhaitez pas ajouter D'attributs spécifiques à JSON.NET.

45
répondu Toby J 2014-10-10 20:37:10

Vous pouvez le faire pour ignorer toutes les valeurs NULL dans un objet que vous sérialisez, et les propriétés null n'apparaîtront pas dans le JSON

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
var myJson = JsonConvert.SerializeObject(myObject, settings);
17
répondu Chris Halcrow 2017-07-06 19:20:18

, Vous pouvez écrire: [JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]

Il prend également soin de ne pas sérialiser les propriétés avec des valeurs par défaut (pas seulement null). Cela peut être utile pour les énumérations par exemple.

11
répondu Er Vatsal D Patel 2018-04-13 15:19:02

Comme on peut le voir dans ce lien sur leur site (http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx) je supporte l'utilisation de [Default ()] pour spécifier les valeurs par défaut

Tiré du lien

   public class Invoice
{
  public string Company { get; set; }
  public decimal Amount { get; set; }

  // false is default value of bool
  public bool Paid { get; set; }
  // null is default value of nullable
  public DateTime? PaidDate { get; set; }

  // customize default values
  [DefaultValue(30)]
  public int FollowUpDays { get; set; }
  [DefaultValue("")]
  public string FollowUpEmailAddress { get; set; }
}


Invoice invoice = new Invoice
{
  Company = "Acme Ltd.",
  Amount = 50.0m,
  Paid = false,
  FollowUpDays = 30,
  FollowUpEmailAddress = string.Empty,
  PaidDate = null
};

string included = JsonConvert.SerializeObject(invoice,
  Formatting.Indented,
  new JsonSerializerSettings { });

// {
//   "Company": "Acme Ltd.",
//   "Amount": 50.0,
//   "Paid": false,
//   "PaidDate": null,
//   "FollowUpDays": 30,
//   "FollowUpEmailAddress": ""
// }

string ignored = JsonConvert.SerializeObject(invoice,
  Formatting.Indented,
  new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });

// {
//   "Company": "Acme Ltd.",
//   "Amount": 50.0
// }
10
répondu Mickey Perlstein 2012-05-09 08:57:45

Une adaptation à la réponse de @Mrchief / @amit, mais pour les personnes utilisant VB

 Dim JSONOut As String = JsonConvert.SerializeObject(
           myContainerObject, 
           New JsonSerializerSettings With {
                 .NullValueHandling = NullValueHandling.Ignore
               }
  )

Voir: "initialiseurs D'objets: types nommés et anonymes (Visual Basic)"

Https://msdn.microsoft.com/en-us/library/bb385125.aspx

4
répondu GlennG 2016-06-14 11:26:24

Pour exposer légèrement la réponse très utile de GlennG (traduire la syntaxe de C # à VB.Net n'est pas toujours "évident") vous pouvez également décorer les propriétés de classe individuelles pour gérer la façon dont les valeurs null sont traitées. Si vous faites cela, n'utilisez pas le JsonSerializerSettings global de la suggestion de GlennG, sinon il remplacera les décorations individuelles. Cela est pratique si vous voulez qu'un élément null apparaisse dans le JSON afin que le consommateur n'ait pas à faire de manipulation spéciale. Si, par exemple, le consommateur doit savoir qu'un tableau d'éléments optionnels est normalement disponible, mais qu'il est actuellement vide... La décoration dans la déclaration de propriété ressemble à ceci:

<JsonPropertyAttribute("MyProperty", DefaultValueHandling:=NullValueHandling.Include)> Public Property MyProperty As New List(of String)

Pour ces propriétés que vous ne voulez pas voir apparaître du tout dans le changement JSON :=NullValueHandling.Inclure à :=NullValueHandling.Ignorer . En passant-j'ai trouvé que vous pouvez décorer une propriété pour la sérialisation XML et JSON très bien (il suffit de les mettre juste à côté de l'autre). Cela me donne de l' l'option d'appeler le sérialiseur XML dans dotnet ou le sérialiseur NewtonSoft à volonté-les deux fonctionnent côte à côte et mes clients ont la possibilité de travailler avec XML ou JSON. Ceci est lisse comme morve sur une poignée de porte depuis que j " ai des clients qui ont besoin à la fois!

0
répondu Destek 2017-07-03 17:34:21

Voici une option qui est similaire, mais qui offre un autre choix:

public class DefaultJsonSerializer : JsonSerializerSettings
{
    public DefaultJsonSerializer()
    {
        NullValueHandling = NullValueHandling.Ignore;
    }
}

Ensuite, je l'utilise comme ceci:

JsonConvert.SerializeObject(postObj, new DefaultJsonSerializer());

, La différence ici est que:

  • réduit le code répété en instanciant et en configurant JsonSerializerSettings chaque endroit utilisé.
  • permet de gagner du temps dans la configuration de chaque propriété de chaque objet à sérialiser.
  • donne toujours aux autres développeurs une flexibilité dans les options de sérialisation, plutôt que d'avoir la propriété explicitement spécifiée sur un réutilisable objet.
  • mon cas d'utilisation est que le code est une bibliothèque tierce et je ne veux pas forcer les options de sérialisation sur les développeurs qui voudraient réutiliser mes classes.
  • les inconvénients potentiels sont que c'est un autre objet que les autres développeurs auraient besoin de connaître, ou si votre application est petite et que cette approche n'aurait pas d'importance pour une seule sérialisation.
0
répondu Joe Mayo 2018-01-07 00:29:40
var settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.NullValueHandling = NullValueHandling.Ignore;
//you can add multiple settings and then use it
var bodyAsJson = JsonConvert.SerializeObject(body, Formatting.Indented, settings);
0
répondu Suresh Bhandari 2018-03-08 21:15:46