2010-02-28 1 views
9

Мой код ниже. Я не могу извлечь списки «имя» и «запрос» из JSON через класс DataContracted (ниже) Я долгое время пытался работать с этим, и мог бы действительно сделать с некоторой помощью .. .Список JSON Twitter в C# .net

Моя 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\""}]}} 

Мой код:

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

Незначительная точка: если вы добавили новое ограничение «где T: new()» к вашему методу Deserialize, вам не понадобится бит Activator.CreateInstance и может просто использовать новый T(). –

ответ

1

Рассмотрим следующий пример:

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; 

Наверное, требуется тонкая настройка, но это общая идея о том, как это сделать.

+0

Я пробовал это, но все равно не ответ, спасибо – James

2

Вы считаете, что используете JSON.net?

+0

Привет, Это не отвечает на вопрос. Я ищу, как это сделать на C#. Я не спрашиваю, где скачать DLL третьей стороны. Спасибо всем тем же. – James

+0

Вот как это сделать на C#. Вы имеете в виду, как это сделать только в .NET Framework. – user7116

+1

(-1) У вас нет (в * любом * пути) указано, почему это лучше, как это использовать, что должен делать OP, если они снова столкнутся с одной и той же проблемой. Кроме того, предполагая, что кто-то полностью начинает что-то без какого-либо знания проекта, обычно не бывает плодотворным. – DevinB

3

Я столкнулся с этой проблемой при разработке Twitterizer. Проблема в том, что набор данных не находится в традиционном объектно-ориентированном дизайне.

Если бы вы были на карте, что в качестве объектов, вы увидите:

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

Как вы можете видеть, объект тенденция имеет свойство, которое меняет имя. Имя основано на значении as_of даты. Таким образом, его нельзя автоматически десериализовать.

Моим первым решением было использовать System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(). Этот метод возвращает иерархию слабо типизированных, вложенных экземпляров словаря. Затем я сам прошел через результаты.

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; 
}

Это некрасиво, но это сработало.

С тех пор я использовал Json.NET для его скорости и простоты.