2010-02-28 15 views
9

Mi código está debajo. No puedo extraer las listas de 'nombre' y 'consulta' del JSON a través de una Clase de DataContracted (abajo) He pasado mucho tiempo tratando de trabajar con este, y realmente podría hacer con alguna ayuda .. .Lista de Twitter JSON en C# .net

cadena

Mi JSON:

{"as_of":1266853488,"trends":{"2010-02-22 
15:44:48":[{"name":"#nowplaying","query":"#nowplaying"},{"name":"#musicmonday","query":"#musicmonday"},{"name":"#WeGoTogetherLike","query":"#WeGoTogetherLike"},{"name":"#imcurious","query":"#imcurious"},{"name":"#mm","query":"#mm"},{"name":"#HumanoidCityTour","query":"#HumanoidCityTour"},{"name":"#awesomeindianthings","query":"#awesomeindianthings"},{"name":"#officeformac","query":"#officeformac"},{"name":"Justin 
Bieber","query":"\"Justin Bieber\""},{"name":"National 
Margarita","query":"\"National Margarita\""}]}} 

Mi código:

WebClient wc = new WebClient(); 
wc.Credentials = new NetworkCredential(this.Auth.UserName, this.Auth.Password); 
string res = wc.DownloadString(new Uri(link)); 
//the download string gives me the above JSON string - no problems 
Trends trends = new Trends(); 
Trends obj = Deserialise<Trends>(res); 


private T Deserialise<T>(string json) 
{ 
    T obj = Activator.CreateInstance<T>(); 
    using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json))) 
    { 
     DataContractJsonSerializer serialiser = new DataContractJsonSerializer(obj.GetType()); 
     obj = (T)serialiser.ReadObject(ms); 
     ms.Close(); 
     return obj; 
    } 
} 


[DataContract] 
public class Trends 
{ 
    [DataMember(Name = "as_of")] 
    public string AsOf { get; set; } 

    //The As_OF value is returned - But how do I get the 
    //multidimensional array of Names and Queries from the JSON here? 
} 
+1

Punto menor: si agregó la nueva restricción "donde T: new()" a su método Deserialize, no necesitaría ese bit Activator.CreateInstance y podría simplemente usar la nueva T(). –

Respuesta

1

Considere este ejemplo:

public struct TwitterResponse 
{ 
    public int32 as_of; 
    public Trend[] Trends; 
} 

public struct Trends 
{ 
    public String name; 
    public String query; 
} 

Trend[] obj = JavaScriptConvert.DeserializeObject<TwitterResponse>(res).Trends; 

Probablemente necesite ajustes finos, pero esa es la idea general de cómo hacerlo.

+0

Intenté esto pero todavía no la respuesta, gracias – James

2

¿Ha considerado usar JSON.net?

+0

Hola, esto no responde la pregunta. Estoy buscando cómo hacer esto en C#. No estoy preguntando dónde descargar un tercero dll. Gracias de todos modos. – James

+0

Así es como hacer esto en C#. Quiere decir cómo hacer esto solo en .Net Framework. – user7116

+1

(-1) No ha indicado (en * cualquier * modo) por qué es mejor, cómo usar esto, qué debería hacer el PO si vuelve a encontrarse con el mismo problema. Además, sugerir que alguien empiece de nuevo por completo sin ningún conocimiento del proyecto no suele ser fructífero. – DevinB

3

Me he encontrado con este mismo problema al desarrollar Twitterizer. El problema es que el conjunto de datos no está en un diseño tradicional orientado a objetos.

Si se va a asignar que como objetos, que se vería:

 
object root 
    int as_of 
    object trends 
    array[object] <date value of as_of> 
     string query 
     string name 

Como se puede ver, el objeto de tendencia tiene una propiedad que es el cambio de nombre. El nombre se basa en el valor as_of date. Como tal, no puede ser deserializado automáticamente.

Mi primera solución fue utilizar System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(). Ese método devuelve una jerarquía de instancias de diccionario anidadas y de tipo débil. Luego revisé los resultados yo mismo.

internal static TwitterTrendTimeframe ConvertWeakTrend(object value) 
{ 
    Dictionary<string, object> valueDictionary = (Dictionary<string, object>)value; 
    DateTime date = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds((int)valueDictionary["as_of"]); 
    object[] trends = (object[])((Dictionary<string, object>)valueDictionary["trends"])[date.ToString("yyyy-MM-dd HH:mm:ss")]; 

    TwitterTrendTimeframe convertedResult = new TwitterTrendTimeframe() 
    { 
     EffectiveDate = date, 
     Trends = new Collection<TwitterTrend>() 
    }; 

    for (int i = 0; i < trends.Length; i++) 
    { 
     Dictionary<string, object> item = (Dictionary<string, object>)trends[i]; 

     TwitterTrend trend = new TwitterTrend() 
     { 
      Name = (string)item["name"] 
     }; 

     if (item.ContainsKey("url")) 
     { 
      trend.Address = (string)item["url"]; 
     } 

     if (item.ContainsKey("query")) 
     { 
      trend.SearchQuery = (string)item["query"]; 
     } 

     convertedResult.Trends.Add(trend); 
    } 

    return convertedResult; 
}

Es feo, pero funcionó.

Desde entonces he abrazado el uso de Json.NET por su velocidad y simplicidad.