Как игнорировать объект во время сериализации (но использовать его позже) [duplicate]

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

377
задан Vito Gentile 1 May 2015 в 14:10
поделиться

10 ответов

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

Вот пример :

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

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

JsonConvert.SerializeObject(myObject, 
                            Newtonsoft.Json.Formatting.None, 
                            new JsonSerializerSettings { 
                                NullValueHandling = NullValueHandling.Ignore
                            });
449
ответ дан Mrchief 18 August 2018 в 16:51
поделиться
  • 1
    Это работает: JsonConvert.SerializeObject (myObject, Newtonsoft.Json.Formatting.None, новый JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}); – Amit 28 June 2011 в 15:34
  • 2
    подробнее здесь: goo.gl/c8Bk1 – Amit 28 June 2011 в 15:41
  • 3
    это сработало для меня, но мне пришлось использовать JsonSerializerSettings not JsonSerializer, поскольку он показал ошибку для последнего – Yazan 24 February 2016 в 09:08
  • 4
    @Язан не должен. Они практически одно и то же. Это может быть что-то другое. – Mrchief 24 February 2016 в 17:41
  • 5
    У меня та же проблема, что и @ chester89. С неиспользуемыми значениями значения ExpandoObject не игнорируются. Кажется, это ошибка (с использованием json.net 9.0.1) – kwrl 5 July 2016 в 09:05

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

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
var myJson = JsonConvert.SerializeObject(myObject, settings);
15
ответ дан CMedina 18 August 2018 в 16:51
поделиться

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

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

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

0
ответ дан Destek 18 August 2018 в 16:51
поделиться

Адаптация к ответу @ Mrchief's / @ 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

4
ответ дан GlennG 18 August 2018 в 16:51
поделиться

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

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

Затем я использую его следующим образом:

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

Разница здесь в том, что:

  • Уменьшает повторяющийся код путем создания и настройки JsonSerializerSettings каждого используемого места.
  • Экономит время при настройке каждого свойства каждого объекта, который будет сериализован.
  • Все еще дает другим разработчикам гибкость в параметрах сериализации, вместо того, чтобы явно указывать свойство на многократно используемом объекте.
  • Мой случай использования заключается в том, что этот код является сторонней библиотекой, и я не хочу принудительно сериализовать варианты для разработчиков, которые хотели бы повторно использовать мои классы.
  • Потенциальными недостатками являются то, что это другой объект, о котором должны знать другие разработчики, или если ваше приложение мало, и этот подход не имеет значения для одного сериализация.
0
ответ дан Joe Mayo 18 August 2018 в 16:51
поделиться

Как видно из этой ссылки на их сайте (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
// }
10
ответ дан Mickey Perlstein 18 August 2018 в 16:51
поделиться

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

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

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

607
ответ дан sirthomas 18 August 2018 в 16:51
поделиться
  • 1
    Принятый ответ лучше, потому что он не загрязняет ваши классы атрибутами Json.net. – Sergey 14 August 2015 в 03:27
  • 2
    @Sergey это зависит от вашего варианта использования. Если вы хотите получить его только для определенных свойств (как упоминалось в вопросе), то это правильный ответ. Если вы хотите получить глобальный ответ, вы должны установить свойство в JsonSerializer. – sibbl 14 January 2016 в 11:05
  • 3
    Согласовано - это просто и элегантно. Стоит выжить. Отлично работает - просто установите свойство в объекте, который вы хотите сериализовать в Nothing в VB, и он больше не является частью JSON. Однако это будет работать только со строками. Свойства, которые представляют собой перечисления или целые числа, всегда будут отображаться - установка в Nothing приводит к значению по умолчанию «0». несмотря на. – Destek 10 April 2017 в 15:50
  • 4
    @Destek вам нужно сделать поля типов ссылок нулевыми, тогда они не будут сериализованы с использованием атрибута или настройки. – Tony 17 January 2018 в 20:53
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
ответ дан Suresh Bhandari 18 August 2018 в 16:51
поделиться

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

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

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

44
ответ дан Toby J 18 August 2018 в 16:51
поделиться
  • 1
    Это так полезно! Я разрабатывал пользовательский класс исключений, и я не хотел добавлять туда материал Json.net. Благодаря! – jpgrassi 10 September 2015 в 20:13
  • 2
    Это не работает в .Net Core. Рекомендовать @sirthomas ответить: использовать [JsonProperty (NullValueHandling = NullValueHandling.Ignore)] – Derrick 4 April 2017 в 00:30
  • 3
    Он отлично работает для меня .Net Core с Newtonsoft.Json 10.0.2. – Karl-Johan Sjögren 7 August 2017 в 14:27

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

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

8
ответ дан user3232354 18 August 2018 в 16:51
поделиться
  • 1
    Это точно так же, как ответ sirthomas, почему вы его добавили? – OMGtechy 23 October 2017 в 16:34
  • 2
    Для вашей любезной информации существует разница между DefaultValueHandling и NullValueHandling ... – Er Vatsal D Patel 25 October 2017 в 09:35
  • 3
    Не могли бы вы объяснить это в своем ответе? На первый взгляд, это выглядит одинаково, и теперь вы упомянули об этом, он не указывает, как это отличается от другого ответа / того, как он его дополняет. – OMGtechy 25 October 2017 в 10:06
  • 4
    Хотя принятый ответ может быть полезен в некоторых обстоятельствах, его не всегда можно использовать. Это именно то, что доктор заказал. – Melbourne Developer 20 June 2018 в 10:05
  • 5
    – frostymarvelous 23 August 2018 в 18:35
Другие вопросы по тегам:

Похожие вопросы: