96 votos

Obtener el valor de JToken que puede no existir (mejores prácticas).

¿Cuál es la mejor práctica para la recuperación de JSON valores que puede incluso no existir en C# usando Json.NET?

Ahora me estoy tratando con un JSON proveedor que devuelve JSON que contiene a veces ciertos pares de clave/valor, y a veces no. He estado usando (tal vez erróneamente) este método para obtener mis valores (por ejemplo para conseguir un doble):

if(null != jToken["width"])
    width = double.Parse(jToken["width"].ToString());
else
    width = 100;

Ahora que funciona bien, pero cuando hay un montón de ellos es engorroso. Terminé de escribir un método de extensión, y sólo después de escrito lo hizo me pregunto si tal vez estaba siendo estúpido... de todos modos, aquí está el método de extensión (que sólo se incluyen los casos de doble y de la 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 he aquí un ejemplo del uso del método de extensión:

width = jToken.GetValue<double>("width", 100);

Por CIERTO, perdón por lo que puede ser una pregunta tonta, ya que parece que algo debe haber una función integrada para... hice todo lo de Google, y Json.NET la documentación, sin embargo estoy bien de ineptos para encontrar la solución a mi pregunta o no está claro en la documentación.

178voto

svick Puntos 81772

Esto es bastante lo que el método genérico Value() . Usted obtener exactamente el comportamiento que usted quiere si se combina con los que aceptan valores null tipos de valor y el ?? operador:

width = jToken.Value<double?>("width") ?? 100;

16voto

L.B Puntos 54001

Me gustaría escribir 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 manera usted puede obtener el valor no sólo de los tipos básicos, sino también de objetos complejos. He aquí 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");

2voto

Dave Van den Eynde Puntos 8199

Usted puede simplemente encasillado, y que va a hacer la conversión para usted, por ejemplo,

var with = (double?) jToken[key] ?? 100;

Volverá automáticamente null si la clave no está presente en el objeto, así que no hay necesidad de la prueba para él.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: