c# - newtonsoft - parse jtoken to jobject
Obtenga valor de JToken que puede no existir(mejores prácticas) (5)
Aquí es cómo puedes verificar si el token existe:
if (jobject["Result"].SelectToken("Items") != null) { ... }
Comprueba si hay "Elementos" en "Resultado".
Este es un ejemplo que NO funciona y que causa una excepción:
if (jobject["Result"]["Items"] != null) { ... }
¿Cuál es la mejor práctica para recuperar valores JSON que ni siquiera existen en C # utilizando Json.NET ?
En este momento estoy tratando con un proveedor JSON que devuelve JSON que algunas veces contiene ciertos pares clave / valor, y otras veces no. He estado usando (quizás incorrectamente) este método para obtener mis valores (ejemplo para obtener un doble):
if(null != jToken["width"])
width = double.Parse(jToken["width"].ToString());
else
width = 100;
Ahora eso funciona bien, pero cuando hay muchos es engorroso. Terminé escribiendo un método de extensión, y solo después de escribirlo me pregunté si tal vez estaba siendo estúpido ... de todos modos, aquí está el método de extensión (solo incluyo casos para doble y cadena, pero en realidad tengo bastantes Más):
public static T GetValue<T>(this JToken jToken, string key,
T defaultValue = default(T))
{
T returnValue = defaultValue;
if (jToken[key] != null)
{
object data = null;
string sData = jToken[key].ToString();
Type type = typeof(T);
if (type is double)
data = double.Parse(sData);
else if (type is string)
data = sData;
if (null == data && type.IsValueType)
throw new ArgumentException("Cannot parse type /"" +
type.FullName + "/" from value /"" + sData + "/"");
returnValue = (T)Convert.ChangeType(data,
type, CultureInfo.InvariantCulture);
}
return returnValue;
}
Y aquí hay un ejemplo del uso del método de extensión:
width = jToken.GetValue<double>("width", 100);
Por cierto, perdona lo que puede ser una pregunta realmente tonta, ya que parece que debería haber una función incorporada para ... Probé la documentación de Google y Json.NET , sin embargo, o soy incapaz de encontrar la solución para mi pregunta o no está claro en la documentación.
Escribiría GetValue
como abajo
public static T GetValue<T>(this JToken jToken, string key, T defaultValue = default(T))
{
dynamic ret = jToken[key];
if (ret == null) return defaultValue;
if (ret is JObject) return JsonConvert.DeserializeObject<T>(ret.ToString());
return (T)ret;
}
De esta forma, puede obtener el valor no solo de los tipos básicos sino también de los objetos complejos. Aquí hay una muestra
public class ClassA
{
public int I;
public double D;
public ClassB ClassB;
}
public class ClassB
{
public int I;
public string S;
}
var jt = JToken.Parse("{ I:1, D:3.5, ClassB:{I:2, S:''test''} }");
int i1 = jt.GetValue<int>("I");
double d1 = jt.GetValue<double>("D");
ClassB b = jt.GetValue<ClassB>("ClassB");
Esto es más o menos para lo que es el método genérico Value()
. ¿Obtienes exactamente el comportamiento que deseas si lo combinas con tipos de valores que se pueden anotar y el ??
operador:
width = jToken.Value<double?>("width") ?? 100;
Simplemente puede encasillar, y hará la conversión por usted, por ejemplo
var with = (double?) jToken[key] ?? 100;
Automáticamente devolverá null
si dicha clave no está presente en el objeto, por lo que no es necesario probarla.
TYPE variable = jsonbody["key"]?.Value<TYPE>() ?? DEFAULT_VALUE;
p.ej
bool attachMap = jsonbody["map"]?.Value<bool>() ?? false;