JSON Twitter список в C # .net - PullRequest
       6

JSON Twitter список в C # .net

9 голосов
/ 28 февраля 2010

Мой код ниже. Я не могу извлечь списки 'name' и 'query' из JSON через класс DataContracted (ниже) Я потратил много времени, пытаясь решить эту проблему, и мог действительно с некоторой помощью ...

Моя строка 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?
} 

Ответы [ 3 ]

3 голосов
/ 11 мая 2010

Я столкнулся с этой самой проблемой при разработке 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 за его скорость и простоту.

2 голосов
/ 04 марта 2010

Вы рассматривали возможность использования JSON.net ?

1 голос
/ 01 марта 2010

Рассмотрим этот пример:

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;

Вероятно, нужно настроить, но это общая идея, как это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...