Как игнорировать свойство в классе, если null, используя json.net

я использую Json.NET для сериализации класса в JSON.

у меня такой класс:

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; }
}

Я хочу добавить до Test2List собственность только тогда, когда Test2List и null. Если это не null, то я хочу включить его в свой json.

10 ответов


согласно Джеймсу Ньютону Кингу: если вы создаете сериализатор самостоятельно, а не используете JavaScriptConvert, есть NullValueHandling свойства который вы можете установить, чтобы игнорировать.

вот пример:

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

альтернативно, как предложено @amit

JsonConvert.SerializeObject(myObject, 
                            Newtonsoft.Json.Formatting.None, 
                            new JsonSerializerSettings { 
                                NullValueHandling = NullValueHandling.Ignore
                            });

альтернативное решение с помощью :

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

Как видно это онлайн doc.


подобно ответу @sirthomas, JSON.NET также уважает на EmitDefaultValue свойства on DataMemberAttribute:

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

Это может быть желательно, если вы уже используете [DataContract] и [DataMember] в вашем типе модели и не хотите добавлять JSON.Net-специфические атрибуты.


вы можете сделать это, чтобы игнорировать все нули в объекте, который вы сериализуете, и любые свойства null не будут отображаться в json

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
var myJson = JsonConvert.SerializeObject(myObject, settings);

вы можете написать: [JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]

Он также заботится о том, чтобы не сериализовать свойства со значениями по умолчанию (не только null). Это может быть полезно для перечислений, например.


Как видно по этой ссылке на их сайте (http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx) я поддерживаю использование [Default ()] для указания значений по умолчанию

взято из ссылки

   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
// }

адаптация к ответу @Mrchief / @amit, но для людей, использующих VB

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

посмотреть: " инициализаторы объектов: именованные и анонимные типы (Visual Basic)"

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


чтобы немного разъяснить очень полезный ответ Гленна (перевод синтаксиса с C# на VB.Net не всегда "очевидно") вы также можете украсить отдельные свойства класса, чтобы управлять обработкой нулевых значений. Если вы это сделаете, не используйте глобальные JsonSerializerSettings из предложения GlennG, иначе он переопределит отдельные украшения. Это удобно, если вы хотите, чтобы нулевой элемент отображался в JSON, поэтому потребителю не нужно выполнять специальную обработку. Если, например, потребитель должен знать, что массив дополнительных элементов обычно доступен, но в настоящее время пуст... Оформление в декларации недвижимости выглядит следующим образом:

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

для тех свойств, которые вы не хотите, чтобы они вообще появлялись в JSON change :=NullValueHandling.Включить to :=NullValueHandling.Игнорировать. Кстати-я обнаружил, что вы можете украсить свойство как для XML, так и для сериализации JSON (просто поместите их рядом с каждым другие.) Это дает мне возможность вызвать XML-сериализатор в dotnet или Newtonsoft serializer по желанию - оба работают бок о бок, и мои клиенты имеют возможность работать с XML или JSON. Это скользко, как сопли на дверной ручке, так как у меня есть клиенты, которые требуют обоих!


вот вариант, который похож, но предоставляет другой выбор:

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

затем я использую его так:

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

разница в том, что:

  • уменьшает повторный код путем создания экземпляра и настройки JsonSerializerSettings каждое место используется.
  • экономит время при настройке каждого свойства каждого объекта для сериализации.
  • все еще дает другим разработчикам гибкость в вариантах сериализации, а не наличие свойство, явно указанное для повторно используемого объекта.
  • мой прецедент заключается в том, что код является сторонней библиотекой, и я не хочу заставлять параметры сериализации разработчиков, которые хотели бы повторно использовать мои классы.
  • потенциальные недостатки заключаются в том, что это еще один объект, о котором должны знать другие разработчики, или если ваше приложение мало, и этот подход не будет иметь значения для одной сериализации.

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);