2011-01-31 80 views
6

Quiero convertir lo que en última instancia es un diccionario en JSON en un diccionario C# sin demasiado preámbulo.
¿Estoy ladrando en el árbol equivocado usando la biblioteca JSON.NET aquí? La clase JArray no quiere darme nada para acceder al atributo (solo el valor), es decir, me dice el valor, pero nunca la "clave".
No puedo creer que nadie más encuentre esta limitación, así que supongo que me estoy perdiendo algo. Mi intento confusa es la siguiente:Usando JSON.NET para acceder a los atributos JSON para crear un diccionario C#

Dada esta JSON:

{ 
"appSettings" : [ 
    {"rows": "5"}, 
    {"columns" : "7"} 
    ] 
} 

me gustaría seleccionar esto en un diccionario como esto:

var dict = jsonObject["appSettings"].Select(s => new 
{ 
    key = s.Name, // wish this property existed 
    value = s.Value // wish this property existed 
}).ToDictionary(s => s.key, s => s.value); 

Ésta es mi unittest:

[Test] 
public void CanLoadJsonAppSettings() 
{ 
var json = @" 
    ""{appSettings"" : [ 
     {""ViewRows"" : ""1""}, 
     {""ViewColumns"" : ""2""} 
    ]}"; 
    var dict = CreateJsonDictionary(json); 
    Assert.That(dict.Count, Is.EqualTo(2)); 
} 

public CreateJsonDictionary(string jsonText) 
{ 
    var jsonObject = JObject.Parse(jsonText); 

    return jsonObject["appSettings"].Select(s => new 
    { 
    key = s.Name, 
    value = s.Value 
    }).ToDictionary(s => s.key, s => s.value); 
} 

EDIT: Gracias a @jim, estamos un poco más cerca. Para completar, documentaré el paso ligeramente incómodo que necesitaba para obtener el objeto que necesitaba:

Tuve que cambiar mi JSON. En lugar de utilizar una matriz (como en el código anterior) que utiliza una forma más sencilla diccionario/más cierto:

var json = @" 
{ 
    ""appSettings"" : { 
    ""ViewRows"" : ""1"", 
    ""ViewColumns"" : ""2"" 
    } 
}"; 

Luego tuve que Analizar, conseguir un JSON jobject, a continuación, convertir de nuevo a una cadena , y luego Deserialize:

var jo = JObject.Parse(jsonText); 
var appSettings = jo["appSettings"]; 
var appSettings = JsonConvert.DeserializeObject<Dictionary<string, string>>(appSettings.ToString()); 

Así que parte de mi problema, era conseguir JSON confundido. Aun así, si hay una forma más elegante de hacerlo, soy todo oídos.

EDIT2: Aún tenía que resolver el problema original anterior, convirtiendo una matriz JSON en un diccionario. Una vez que mi JSON se corrige para contener pares nombre/valor apropiado:

"connectionStrings": [ 
{"name" : "string1", "value" : "value1"}, 
{"name" : "string2", "value" :"value2"}, 
] 

Este es el código que lo resolvió (nb se parece mucho a mi intento inicial):

var jsonObj = JObject.Parse(jsonText); 
var conStrings = jsonObj.Properties().Select(s => 
    new { 
    key = s.Name, 
    value = s.Value.ToString() 
}).ToDictionary(s => s.key, s => s.value); 

Y esto sólo funciona si no tienes otras matrices

Respuesta

0

Sé que no es la respuesta correcta para su pregunta, pero para todas las cosas de JSON en C# aquí hay un enlace para una muy buena biblioteca que puede usar para hacer cualquier cosa con JSON en C#.

http://james.newtonking.com/pages/json-net.aspx

+1

en realidad estoy usando la biblioteca JSON.NET en mi pregunta. Fue parte del problema. – PandaWood

11

Panda,

textuales de James Newton mismo rey de SO a una pregunta similar:

// Json.NET does this... 

string json = @"{""key1"":""value1"",""key2"":""value2""}"; 
Dictionary<string, string> values 
    = JsonConvert.DeserializeObject<Dictionary<string, string>>(json); 

se puede encontrar el hilo aquí:

How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?

espero que esto ayude (aunque no t 100% seguro de cómo funciona esto con estructuras arbóreas complejas)

+0

Esta es la misma biblioteca que YvesR ya tiene enlaces;) –

+0

David, lo sé :-), de ahí mi información adicional sobre esa biblioteca. de hecho hice referencia a la respuesta adicional puramente basada en eso, de lo contrario, habría 'hecho cumbre de lo demás' - sin preocupaciones (icono de guiño) –

2

Esta es la manera MS de hacer esto, pero es bastante complejo y realmente creo que la solución de YvesR podría ser más fácil de implementar.

http://atsung.wordpress.com/2008/08/07/javascriptserializer-example/

+0

alguien pensó que no :) Recibí menos votos por el mío. – YvesR

+0

YvesR, no era yo: -}. creo que fue un voto negativo pobre también. Odio cuando esto sucede y ¡no quedan comentarios! - No tiene sentido –

1

Convertir array assosiative js en diccionario, uso puede utilizar convertidor que es el siguiente:

using System; 
using System.Collections.Generic; 
using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 

namespace MyJsonConverters 
{ 
    public class AssosiativeArrayConverter : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      return objectType.GetInterface(typeof(IDictionary<,>).Name) != null; 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      JObject jObject = JObject.Load(reader); 

      var result = Activator.CreateInstance(objectType); 
      var addMethod = result.GetType().GetMethod("Add"); 
      var dictionaryTypes = objectType.GetGenericArguments(); 

      foreach (JProperty property in jObject.Properties()) 
      { 
       var key = Convert.ChangeType(property.Name, dictionaryTypes[0]); 

       var value = serializer.Deserialize(property.Value.CreateReader(), dictionaryTypes[1]); 

       addMethod.Invoke(result, new[] { key, value }); 
      } 

      return result; 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

entonces el uso es el siguiente:

Dictionary<string, string> dictionary; 
dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(value, new AssosiativeArrayConverter); 

donde T es su Diccionario, por ejemplo Diccionario o lo que quieras

JSON que se deserialized en mi caso se ve como sigue:

{ "MyDictionary": { "key1": [ "valor1", "valor2", "valor3" ] , "clave2": []}

+0

hey, buen enfoque +1 –

Cuestiones relacionadas