Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON Twitter List in C#.net

Tags:

json

c#

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?
} 
like image 280
James Avatar asked Feb 28 '10 20:02

James


People also ask

Does Twitter use JSON?

All Twitter APIs that return Tweets provide that data encoded using JavaScript Object Notation (JSON). JSON is based on key-value pairs, with named attributes and associated values. These attributes, and their state are used to describe objects. At Twitter we serve many objects as JSON, including Tweets and Users.

How do I find my Twitter list ID?

The id of a twitter list can be found by looking at end end of the URL of the list on twitter web, for example in the url https://twitter.com/i/lists/1269293736644796416 , 1269293736644796416 would be the id.

Is there an API for Twitter?

The Twitter API enables programmatic access to Twitter in unique and advanced ways. Tap into core elements of Twitter like: Tweets, Direct Messages, Spaces, Lists, users, and more. Twitter for Websites brings live conversation from Twitter to your website or app.


3 Answers

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.

like image 63
Ricky Smith Avatar answered Oct 16 '22 18:10

Ricky Smith


have you considered using JSON.net ?

like image 36
AndreasKnudsen Avatar answered Oct 16 '22 18:10

AndreasKnudsen


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.

like image 1
Theofanis Pantelides Avatar answered Oct 16 '22 19:10

Theofanis Pantelides