Как игнорировать свойство в классе, если 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; }
}

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

Ответ 1

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

Здесь пример:

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

В качестве альтернативы, как было предложено @amit

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

Ответ 2

Альтернативное решение с использованием атрибута JsonProperty:

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

// or for all properties in a class
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]

Как видно из этого онлайн-документа.

Ответ 3

Как и @sirthomas, JSON.NET также уважает свойство EmitDefaultValue на DataMemberAttribute:

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

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

Как видно из этой ссылки на их сайте (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
// }

Ответ 8

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

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

Для этих свойств вы не хотите вообще появляться в изменении JSON : = NullValueHandling.Include до : = NullValueHandling.Ignore. Кстати, я обнаружил, что вы можете украсить свойство как для XML, так и для JSON-сериализации просто отлично (просто поместите их рядом друг с другом). Это дает мне возможность называть сериализатор XML в dotnet или сериализаторе NewtonSoft по своему усмотрению - оба работают бок о бок, а мои клиенты имеют возможность работать с XML или JSON. Это гладкий, как сопли на дверной ручке, так как у меня есть клиенты, которые требуют обоих!

Ответ 9

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

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

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

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

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

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

Ответ 10

В .Net Core это теперь намного проще. В вашем файле startup.cs просто добавьте параметры json, и вы сможете настроить их там.


public void ConfigureServices(IServiceCollection services)

....

services.AddMvc().AddJsonOptions(options =>
{
   options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;               
});

Ответ 11

С Json.NET

 public class Movie
 {
            public string Name { get; set; }
            public string Description { get; set; }
            public string Classification { get; set; }
            public string Studio { get; set; }
            public DateTime? ReleaseDate { get; set; }
            public List<string> ReleaseCountries { get; set; }
 }

 Movie movie = new Movie();
 movie.Name = "Bad Boys III";
 movie.Description = "It no Bad Boys";

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

Результат будет:

{
   "Name": "Bad Boys III",
   "Description": "It no Bad Boys"
 }

Ответ 12

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