Solución:
Asumiendo Values
es un List<MyObject>
y tu MyObject
la clase se ve así:
class MyObject
{
public string Time { get; set; }
public int Level { get; set; }
}
puede reemplazar todo ese código con lo siguiente para obtener el resultado que desea:
string json = File.ReadAllText(fileName);
Values = JToken.Parse(json)["docs"].ToObject<List<MyObject>>();
Esto funciona porque Json.Net ignorará las propiedades faltantes de forma predeterminada. Desde el MyObject
la clase no contiene un _id
para deserializar, no es necesario pasar por aros tratando de eliminarlo del JSON.
Explicación de por qué Remove()
no funcionó
JToken.Remove()
elimina un JToken
de su padre. Es legal eliminar un JProperty
de su padre JObject
, o para sacar a un niño JToken
a partir de una JArray
. Sin embargo, no puede eliminar el valor de un JProperty
. A JProperty
siempre debe tener exactamente un valor.
Cuando pides token["_id"]
tu recuperas el valor de El JProperty
llamado _id
, no la JProperty
sí mismo. Por lo tanto, obtendrá un error si intenta llamar Remove()
en ese valor. Para que funcione de la forma en que lo está haciendo, debe usar Parent
como esto:
if (inner["_id"] != null)
inner["_id"].Parent.Remove();
Esto dice “Encuentra la propiedad cuyo nombre es _id
y dame el valor. Si existe, obtenga el padre de ese valor (la propiedad) y elimínelo de su padre (el JObject
). “
Una forma más sencilla de hacerlo es utilizar el Property()
método para acceder a la propiedad directamente. Sin embargo, este método solo está disponible en JObject
, no JToken
, por lo que tendría que cambiar la declaración de inner
a un JObject
o lanzarlo:
foreach (JObject inner in token["docs"].Children<JObject>())
{
JProperty idProp = inner.Property("_id");
if (idProp != null)
idProp.Remove();
...
}
Por último, como se menciona en los comentarios, si está usando C # 6 o posterior, puede acortar un poco el código usando el operador condicional nulo:
inner.Property("_id")?.Remove();