C # JsonPath JToken.Remove [дублировать]

16
задан Miguel 20 February 2014 в 07:37
поделиться

2 ответа

Предполагая, что Values является List<MyObject>, а ваш класс MyObject выглядит следующим образом:

class MyObject
{
    public string Time { get; set; }
    public int Level { get; set; }
}

вы можете заменить весь этот код следующим, чтобы получить желаемый результат:

string json = File.ReadAllText(fileName);
Values = JToken.Parse(json)["docs"].ToObject<List<MyObject>>();

Это работает, потому что Json.Net будет игнорировать отсутствующие свойства по умолчанию. Поскольку класс MyObject не содержит свойство _id для десериализации в, вам не нужно прыгать через обручи, пытаясь удалить его из JSON.

Объяснение причины Remove() didn ' t work

JToken.Remove() удаляет JToken из своего родителя. Исключить JProperty из его родителя JObject или удалить дочерний элемент JToken из JArray законно. Однако вы не можете удалить значение из JProperty. JProperty всегда должно иметь ровно одно значение.

Когда вы запрашиваете token["_id"], вы возвращаете значение в JProperty, называемое _id, а не JProperty. Поэтому вы получите сообщение об ошибке, если попытаетесь вызвать Remove() на это значение. Чтобы заставить его работать так, как вы это делаете, вам нужно будет сделать это:

if (inner["_id"] != null)
    inner["_id"].Parent.Remove();

Это говорит: «Найдите свойство, имя которого _id и дайте мне значение. Если оно существует, получить родительский элемент этого значения (свойство) и удалить его из родительского объекта (содержащего JObject).

Другой способ сделать это, возможно, более ясен:

JProperty id = inner.Children<JProperty>().FirstOrDefault(p => p.Name == "_id");
if (id != null)
    id.Remove();
47
ответ дан Brian Rogers 18 August 2018 в 19:33
поделиться
  • 1
    Спасибо, очень полезно знать, что Json.net игнорирует дополнительные свойства. Тем не менее, мне все равно хотелось бы знать, почему я не могу удалить () поля. – Miguel 20 February 2014 в 08:56
  • 2
    Я обновил свой ответ, чтобы добавить объяснение, которое вы просили. – Brian Rogers 20 February 2014 в 18:36
  • 3
    Спасибо огромное! Это именно то объяснение, которое я искал! – Miguel 21 February 2014 в 05:13
  • 4
    Нет проблем; рад помочь. – Brian Rogers 21 February 2014 в 05:17

Основываясь на бриллианском ответе Брайана, вы можете сделать это просто в своем случае:

var inner_id = inner["_id"] as JProperty;
if (inner_id != null)
  inner_id.Remove();
-2
ответ дан awe 18 August 2018 в 19:33
поделиться
  • 1
    Извините, это не сработает. Как я сказал в своем ответе, использование синтаксиса индексатора даст вам значение JProperty, а не самого JProperty. Значение никогда не будет JProperty, потому что JProperties не может напрямую содержать другие JProperties. Поэтому, когда вы пытаетесь применить выражение inner["_id"] к JProperty, как вы здесь делаете, оно всегда будет null, и поэтому Remove() никогда не будет вызываться. Посмотрите сами: dotnetfiddle.net/EkTU4o – Brian Rogers 8 April 2016 в 15:41
  • 2
    Ах ... Это сбивает с толку, но у меня есть это сейчас. Внезапно код в моем проекте работает по назначению! Несмотря на то, что мой ответ неверен, я позволил ему показать пример того, как не делать этого ... – awe 26 October 2016 в 11:07
Другие вопросы по тегам:

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