开发者

JSON Twitter List in C#.net

My code is below. I am not able to extract the 'name' and 'query' lists from the JSON via a DataContracted Class (below) I have spent a long time trying to work this one out,开发者_运维技巧 and could really do with some help...

My Json string:

{"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\""}]}}

My code:

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


I've run into this very issue while developing Twitterizer. The issue is that the dataset isn't in a traditional object-oriented design.

If you were to map that as objects, you would see:

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

As you can see, the trend object has a property that's name changes. The name is based on the as_of date value. As such, it can't be automatically deserialized.

My first solution was to use System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(). That method returns a hierarchy of weakly typed, nested dictionary instances. I then stepped through the results myself.

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

It's ugly, but it worked.

I've since embraced the use of Json.NET for it's speed and simplicity.


have you considered using JSON.net ?


Consider this example:

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;

Probably needs finetuning, but that's the general idea on how to do it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜