Предполагая, что 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();
Основываясь на бриллианском ответе Брайана, вы можете сделать это просто в своем случае:
var inner_id = inner["_id"] as JProperty;
if (inner_id != null)
inner_id.Remove();
JProperty
, а не самого JProperty
. Значение никогда не будет JProperty
, потому что JProperties
не может напрямую содержать другие JProperties
. Поэтому, когда вы пытаетесь применить выражение inner["_id"]
к JProperty
, как вы здесь делаете, оно всегда будет null
, и поэтому Remove()
никогда не будет вызываться. Посмотрите сами: dotnetfiddle.net/EkTU4o
– Brian Rogers
8 April 2016 в 15:41