SilverTweet – Building a Silverlight Twitter client part 1

A while back, I wrote this blog series about how to build a Silverlight client for flickr. This seemed to be pretty popular among a bunch of the people who stumble across my blog. I don’t know if it was specifically because it was using flickr or if it was because it went through the entire application step by step or if it was something else. But since then, I have gone around thinking about other possible applications that I could dissect in the same way, and for some odd reason I stumbled across Twitter. I know…you don’t stumble across Twitter. It is all over the place, and anybody that hasn’t heard of it is probably dead or deaf  and blind. I’m personally not that active on Twitter, even though I try on and off. For anyone interested, I’m available here.

Anyhow, after having looked at it for a while, I decided to create a Silverlight based Twitter application. Even though it’s not as fancy or useful as some of the other alternatives out there, it will show the basics behind how to build a client. And not a client that just allows you to read a feed, but actually interact with it and send tweets. If you are not interested in how to develop a Twitter client and just want a Silverlight based client, I would recommend Gadfly, which is a fantastic client compared to what I’m going to show. But the idea behind this blog series is not to get the coolest application, but have a look at how one could go about building a client.

The first step to getting started with a Twitter client is of course to get a Twitter account. This is easy, just run over to Twitter.com and sign-up if you haven’t already. After that, it is time to have a look at how you interact with Twitter. All of this information is readily available at Twitter’s developer wiki. Here you can find everything you need.

You will quickly find out three things about Twitter. First of all you will realize that the entire API is REST based. That means that all functionality is exposed using simple HTTP GET and POST requests to their server. The second thing you realize is that to be allowed to actually interact with a persons Twitter account, you need to get some form authorization going. And the third one is that there are a bunch of pre-built libraries that you can download and that will manage all communication with Twitter.

So…let’s start off by agreeing that I am not going to use a pre-built library. I’ve already seen a couple of blogs explaining how to create a Silverlight Twitter client using a pre-built library. That is probably the fastest and simplest way of doing it, but it is really boring. I want to take it from one end of the system to the other…a FULL application, not just a little shell that lives on top of somebody’s API library.

After I got that off my chest, it is time to take a look at authentication and authorization for Twitter. Twitter currently supports 2 forms of authentication, basic authentication and OAuth. The obvious way to build a client fast and simple would be to use basic authentication. That way, you just pass the username and password over the wire with each call. However, there are 3 downsides to this. First off, this is very insecure. The username and password will be passed back and forth between the client and Twitter in clear text… The next one is that Twitter stop supporting this in the future. It might be a long time until they do, but they will. OAuth on the other hand will live on, and is an open standard used not only by Twitter. So learning to use it is good. And finally, by having to pass username and password with the requests, means that the application must know these. Basically I need to tell the user of my client to hand over his or her credentials, which might be used in malicious ways.

So I have obviously opted for OAuth, which is a bit tedious and “interesting” in some ways, but still the best option. Once again, there are pre-built libraries…all of which I will ignore. I would however like to give shout out to Eran Sandler who created a basic C# class for performing OAuth signing. I haven’t used that as such, but I have borrowed pieces of that code in my implementation. But mostly, it explained how to do signing in a way that nobody else managed to do. Code says it so much better than words… :)

I started out with the idea that everything would be placed in my Silverlight application, which would perform all communication with Twitter. Unfortunately, this grinded to a complete stop quite quickly. Reading a feed (called Timeline on Twitter) is simple to do using Silverlight. That is just a HTTP GET request. However, as soon as you start looking at using OAuth and performing HTTP POST requests it all fails. Silverlight can’t do cross domain POST calls. A limitation that it shares with XMLHttpRequest. I found that out pretty quickly, since I decided that I might try using the JavaScript bridge to call out to the XMLHttpRequest object. Unfortunately this didn’t work. So I had to figure out a solution for this. And I guess there are two, which both include one sucky point…my server… I have to let the Silverlight client call back to the hosting server, which can then do one of two things. It can either work as a relay station and just forward my request as a proxy server, or expose webservices with the required functionality and let them talk to Twitter.

Since the server would have to be involved anyway, I decided for the latter. I might as well put the communication logic there and give the client a nice API to work against. This also makes it possible for me to create other clients for that functionality.

So, let’s get started with creating the application… Unfortunately there is a little bit more involved before we can go on. We need to have a look at how OAuth works. Since OAuth is all about security, it doesn’t at any point involve the client having access to the users username and password. Instead it works like this

  1. The client sends a request to Twitter (or whoever uses OAuth and you want to interact with) and requests an authorization token. This token is created based on some parameters sent to Twitter. In the response the client gets a token that can be used to generate a URL used in step 2
  2. The user is told to visit this URL, login and authorize the application to interact with the persons account.
  3. Twitter gives the user a PIN number and tells the user to return to the client
  4. The user feeds in the PIN code in the application
  5. The application contacts Twitter and tells it that it wants to exchange its authorization token for and access token, passing along the authorization token and the PIN number
  6. Twitter returns an access token.

This access token can then be used together with the PIN to access the users Twitter account until the user specifically tells Twitter to revoke that token. So the initial startup of the application will be a little cumbersome, but in the end it is worth it. Twitter supports a couple of other flows as well. You might especially be interested in the flow that redirects the user to a designated URL after having authorized the client. But I opted for this solution for a some reason…

So, how does Twitter know what application is trying to communicate with it? And how can this be secure when there is all of this information flying over the wire? Well, because it is all signed and includes a “consumer key” and a “consumer secret” that Twitter knows about. The key is sent back and forth with the requests, but the signature is generated using the secret. That way, Twitter can see who is calling by looking at the key, but also verify if the call is coming from the client and has not been modified. Pretty smart right…

But to be able to do what I have been talking about, you need a consumer key and secret. These can be generated by visiting http://twitter.com/oauth_clients. Here you can register your client and get your key and secret. This is by the way also a good reason to go via the server for the Silverlight communication. Otherwise, the secret would be compiled in the assembly in the Xap, and thus pretty easy to get hold of…

After having generated a key and a secret, it is time to get started. I started my Twitter application by handling the login methods. So I created a class that I called Twitter. Might have been smarter to call it something better, but I am not the most imaginative guy when it comes to names… Since I know that I can never communicate with Twitter without a key and secret, I added these as parameters to the constructor. I actually created 2 constructors. One that takes a key and a secret, and one that also takes an AccessToken. The second constructor will be used as soon as the user has gone through the registration procedure and the application has an AccessToken to use. It looks like this

public class Twitter
{
const string BASE_URL = "http://twitter.com/";
private AccessToken _accessToken;
private string _consumerKey;
private string _consumerSecret;

public Twitter(string consumerKey, string consumerSecret) : this(consumerKey, consumerSecret, null)
{
}
public Twitter(string consumerKey, string consumerSecret, AccessToken accessToken)
{
_consumerKey = consumerKey;
_consumerSecret = consumerSecret;
_accessToken = accessToken;
}
}

 

As you can see, I have also added a constant that holds the base address to the Twitter REST API. Why? Well…it’s nice having it in one place instead of spread out. And because I theoretically might be able to re-use this if some other service starts using OAuth.

If you look in the text above, you will see that step one in authenticating with Twitter is to request an authorization token. This is then used to create a URL and so on. To make the procedure simpler, I decided to wrap it up into one method called GetAuthorizationUrl. It returns a URL and has an out parameter for the actual authorization token.

public string GetAuthorizationUrl(out AuthToken authToken)
{
string resp = CallTwitterGetMethod("oauth/request_token", new List<QueryParameter>(), false);
authToken = AuthToken.Parse(resp);
return BASE_URL + "oauth/authorize?oauth_token=" + HttpUtility.UrlEncode(authToken.Token) + "&" + OAuthUtility.CallbackKey + "=oob";
}

The code above shows you exactly what is happening. Unfortunately most of the functionality is not visible since it is placed in other methods. So let’s dissect the involved code. But I will leave the CallTwitterGetMethod to the end, since it is the most complex.

The AuthToken class is not that complicated. It’s a class that holds 2 string properties, Token and TokenSecret. The AuthToken class implements a static Parse method to parse the response from Twitter. The response from Twitter will look something like this:

oauth_token=32844063-LcJ31sTP3RUVx8svgBkneFeuNgehmbmCLPOcDRGAp&oauth_token_secret=wnhwGIE8Qyh0l2V3uY9gT5mpuroENlrkN5TSu347BLU

So it needs to be parsed to get the useful pieces. The AuthToken class looks like this

[DataContract]
public class AuthToken
{
public AuthToken(string token, string tokenSecret)
{
Token = token;
TokenSecret = tokenSecret;
}

public static AuthToken Parse(string str)
{
string[] parts = str.Split('&');
string token = parts[0].Split('=')[1];
string tokenSecret = parts[1].Split('=')[1];
return new AuthToken(token, tokenSecret);
}

[DataMember]
public string Token { get; private set; }

[DataMember]
public string TokenSecret { get; private set; }
}

 

The only real functionality is the Parse method. I have also added DataContract and DataMember attributes to this class so that it can be used for webservices…more about this in later blog posts…

In the GetAuthorizationUrl I am then concatenating the base URL with the address of the authorization page, appending the token as well as a callback key. The OAuthUtility class is a utility class (duh…) containing helper methods as well as constants for the parameter name strings used when communicating with Twitter. So OAuthUtility.CallbackKey is just a const string with the value “oauth_callback”. I also make sure to UrlEncode the token.

So, what’s the magic in the CallTwitterGetMethod? Well…there is no magic at all. It is a method that helps out with the GET requests to Twitter. It has a sibling called CallTwitterPostMethod that helps with out with the POST requests.

The CallTwitterGetMethod takes 3 parameters. The name of the method to call, a list of QueryParamters to pass and a boolean indicating it is a call to a method that requires authentication. These parameters makes it possible to use this method to call any GET method on Twitter in a simple way. In the case of the CallTwitterGetMethod, I am passing in the method “oauth/request_token”, an empty list of parameters and false.

The QueryParameter class is a very simple. It basically a name/value class..

public class QueryParameter
{
public QueryParameter(string name, string value)
{
Name = name;
Value = value;
}
public string Name { get; private set; }
public string Value { get; private set; }
}

The first thing that the CallTwitterGetMethod does, is to verify if the call requires authentication. Depending on this, it calls one of two overloads for a method called GetSignedUrl. The GetSignedUrl is responsible for taking the different parts of the request and generate the URL to be used. This includes a few step. But lets first look at the rest of the CallTwitterGetMethod, just accepting that the GetSignedUrl method will give us a useful URL.

As soon as a URL has been created, the method instantiates a new HttpWebRequest, sets its Timeout a little higher configures it to use GET. After that, it makes the request and gets the response. It then returns the response as a string for further parsing. It looks like this

public string CallTwitterGetMethod(string methodName, List<QueryParameter> parameters, bool requiresAccessToken)
{
string url = null;
if (requiresAccessToken)
{
url = GetSignedUrl(BASE_URL + methodName, parameters, "GET", _accessToken.Token, _accessToken.TokenSecret);
}
else
{
url = GetSignedUrl(BASE_URL + methodName, parameters, "GET");
}

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 10000;
req.Method = "GET";

string response = null;
StreamReader sr = null;
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
sr = new StreamReader(resp.GetResponseStream());
response = sr.ReadToEnd();
}
finally
{
if (sr != null)
sr.Close();
}
return response;
}

 

So, lets go back to that mysterious GetSignedUrl method. That has to be magical…well…not really. But it does encapsulate some tedious work. First of all, it must gather all the parameters needed to make the call. Every single call to Twitter needs at least 5 parameters. So even if the call to GetSignedUrl passes an empty list of parameters, it will automatically add the necessary 5. The 5 required parameters are: oauth_version, oauth_nonce, oauth_timestamp, oauth_signature_method and oauth_consumer_key. The version is always 1.0. The timestamp is the current time represented as seconds since January 1 1970 (sweet!!!). The signature method used is HMAC-SHA1, which is the only one supported by Twitter. The consumer key is of course the key that Twitter has assigned our application. And finally, the nonce. The nonce is basically just a string that should be unique for the used timestamp. Only ASCII values are accepted by Twitter.

As you can see, there are two overloads. One with a token and token secret and one without. The one without just forwards the request to the other overload, passing String.Empty for those parameter. If a token is available, this is added as a parameter as well.

All parameters are then sorted alphabetically by name, before being concatenated into a querystring format, that is parameterName=value&parameterName2=value2. Finally, another string is created by concatenating the HTTP method being used (upper case) with the URL to the API method to call and finally with the querystring just created. The parts of the string are combined with an ampersand separating them. The end result would look something like this

GET&http://twitter.com/methodname&parameter1=value1&parameter2=value2

A hash is then generated from this string, using the consumer secret as the key. Finally, the signed URL is created by concatenating the URL, the querystring and adding the signature as a final querystring parameter.

protected string GetSignedUrl(string url, List<QueryParameter> parameters, string httpMethod, string token, string tokenSecret)
{
parameters.Add(new QueryParameter(OAuthUtility.VersionKey, "1.0"));
parameters.Add(new QueryParameter(OAuthUtility.NonceKey, OAuthUtility.GenerateNonce()));
parameters.Add(new QueryParameter(OAuthUtility.TimestampKey, OAuthUtility.GenerateTimeStamp()));
parameters.Add(new QueryParameter(OAuthUtility.SignatureMethodKey, "HMAC-SHA1"));
parameters.Add(new QueryParameter(OAuthUtility.ConsumerKeyKey, _consumerKey));
if (!string.IsNullOrEmpty(token))
{
parameters.Add(new QueryParameter(OAuthUtility.TokenKey, token));
}

OAuthUtility.SortParameters(parameters);

StringBuilder reqParams = new StringBuilder();
foreach (var param in parameters)
{
reqParams.AppendFormat("{0}={1}&", param.Name, param.Value.OAuthUrlEncode());
}
string normalizedRequestParameters = reqParams.ToString().TrimEnd('&');

StringBuilder signatureBase = new StringBuilder();
signatureBase.AppendFormat("{0}&", httpMethod.ToUpper());
signatureBase.AppendFormat("{0}&", url.OAuthUrlEncode());
signatureBase.AppendFormat("{0}", normalizedRequestParameters.OAuthUrlEncode());

string signature = OAuthUtility.HMACSHA1Encode(_consumerSecret, tokenSecret, signatureBase.ToString());

return url + "?" + normalizedRequestParameters + "&" + OAuthUtility.SignatureKey + "=" + HttpUtility.UrlEncode(signature);
}

There are a few interesting things to note in the previous code. First of all, I have some helpers in the OAuthUtility class for creating the Timestamp and the nonce. They are simple little things

public static string GenerateNonce()
{
return _random.Next(123400, 9999999).ToString();
}
public static string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}

 

You might also have noticed that I am calling a method called OAuthUrlEncode on my strings. The reason for this is that before the generation of the hash, the strings must be URL encoded. Unfortunately, the HttpUtility.UrlEncode method in the framework doesn’t work. Why? Well, when UrlEncoding your parameters, any encoded character should be encoded using %xx. The xx is hex and the HttpUtility version uses the wrong casing for this. So I created an extension method to the String class to handle this for me. It looks like this

public static string OAuthUrlEncode(this string value)
{
StringBuilder result = new StringBuilder();

foreach (char symbol in value)
{
if (ALLOWED_CHARS.IndexOf(symbol) != -1)
{
result.Append(symbol);
}
else
{
result.Append('%' + String.Format("{0:X2}", (int)symbol));
}
}

return result.ToString();
}

So, after that huge sidestep looking at all sorts of helpers, I am done with the code needed to complete the GetAuthorizationUrl method. After the user has used this URL to authorize the application, it is time to use the acquired PIN code to exchange the authorization token for an access token. This is done in the GetAccessToken method. This method is a little special. It is the only method I have created that doesn’t use any of the request helper methods. Why? Well, it was simpler to do it manually for this one.

What makes that method so special? Well, nothing really, but I had a hard time to get my helpers to work nicely with 2 different kind of tokens without making them complicated. In this case, I need to pass both my authorization token as well as my access token. So this is how I implemented it.

First of all, the method needs two parameters. The PIN and the authorization token from the previous method. After that, it creates a list of QueryParameters. The list is populated with one single parameter, the oauth_verifier parameter. The value for it is the PIN. After that it calls the GetSignedUrl method. However, this time it passes in the method name “oauth/access_token” and POST as HttpMethod. It then simply uses a WebClient to make the request and download the response. It is kind of funky that this works. Twitter expects this to be a POST, but has no problems what so ever to handle a GET request with the parameters passed as querystring parameters… Nice! Finally, it creates a AccessToken class by calling its Parse method.

public AccessToken GetAccessToken(string pin, AuthToken authToken)
{
List<QueryParameter> parameters = new List<QueryParameter>();
parameters.Add(new QueryParameter(OAuthUtility.VerifierKey, pin));
string url = GetSignedUrl(BASE_URL + "/oauth/access_token", parameters, "POST", authToken.Token, authToken.TokenSecret);
WebClient client = new WebClient();
string resp = client.DownloadString(url);
return AccessToken.Parse(resp, pin);
}

 

The AccessToken class is more or less identical to the AuthToken, but holds 2 more properties, the PIN and the ScreenName for the user. So I won’t show it…

That was two methods down. Three to go. However, they are much simpler since we have already seen most of the helper methods…

Lets start by looking at the final “user account method”, the VerifyCredentials method. This method can be called to verify that the users haven’t revoked the access token since last use of the application. The REST API method name is “account/verify_credentials.xml”. The “.xml” tells the system to return the information as XML. It is also possible to get the result as Atom or RSS or JSON. But I like XML. It takes no parameters except the required ones. So the call looks like this

public User VerifyCredentials()
{
string response;
List<QueryParameter> parameters = new List<QueryParameter>();
try
{
response = CallTwitterGetMethod("account/verify_credentials.xml", parameters, true);
}
catch (Exception ex)
{
HandleException(ex);
return null;
}
XDocument doc = XDocument.Parse(response);
return User.Parse(doc.Root);
}

 

As you can see, it returns a User object. Once again, I have created a static Parse method to handle the extraction of information from the Xml document. The User object is just another simple object with properties corresponding to the values returned from Twitter in Xml form. The properties are ID, Name, ScreenName, Location, Description and ProfileImageUrl. The Location is still not really implemented, but I liked the idea of using it in future experiments. The class also has DataContract and DataMember attributes for passing over the wire.

The final two methods in the Twitter class is about getting the the users timeline (the feed) and updating the users status (tweeting). Lets start by looking at the users feed.

Once again, the code is pretty much the same as the previous methods. As soon as you got the “helper” methods down, the actual methods using them tend to be simple. This also makes it VERY easy to extend this class to support more of the Twitter API. The GetTimeline method takes two nullable parameters, sinceId and count. The sinceId parameter will tell Twitter only to get tweets tweeted after the tweet with ID=sinceId was tweeted. And the count is the amount of tweets to get back. If either  of these aren’t null, they are added to the QueryParameter list. After that the CallTwitterGetMethod is used to call the “statuses/friends_timeline.xml” method. The response is then read into a XDocument, which is then traversed using a Linq expression pulling out Tweet objects.

public Tweet[] GetTimeline(long? sinceId, int? count)
{
string response;
List<QueryParameter> parameters = new List<QueryParameter>();
if (sinceId.HasValue)
{
parameters.Add(new QueryParameter("since_id", sinceId.Value.ToString()));
}
if (count.HasValue)
{
parameters.Add(new QueryParameter("count", count.Value.ToString()));
}
try
{
response = CallTwitterGetMethod("statuses/friends_timeline.xml", parameters, true);
}
catch (Exception ex)
{
HandleException(ex);
return null;
}
XDocument doc = XDocument.Parse(response);
var tweetQuery = from tweet in doc.Descendants(XName.Get("status"))
select Tweet.Parse(tweet);
return tweetQuery.ToArray();
}

The Tweet class is, just like the token classes and the User class, “instantiations” of the returned Xml and implements a Parse method. The only interesting part of that class is the way it parses the creation date property. Twitter returns the date in a somewhat useless format, e.g. Wed Sep 16 04:13:03 +0000 2009. So this needs to be manually parsed. I did it using the following method, but I have seen some other ways of doing it

static DateTime ParseDateTime(string date)
{
string dayOfWeek = date.Substring(0, 3).Trim();
string month = date.Substring(4, 3).Trim();
string dayInMonth = date.Substring(8, 2).Trim();
string time = date.Substring(11, 9).Trim();
string offset = date.Substring(20, 5).Trim();
string year = date.Substring(25, 5).Trim();
string dateTime = string.Format("{0}-{1}-{2} {3}", dayInMonth, month, year, time);
DateTime ret = DateTime.Parse(dateTime);
return ret;
}

 

The final method in the Twitter class is the one used to tweet, or as Twitter calls it, update the users status. Once again the method is quite simple. It passes along two QueryParameters to a helper method method, one with the new status and one with the PIN used to create the AccessToken. The main difference is that it calls a different helper than before. The previous methods have used HTTP GET and not POST. This uses POST and thus needs a different implementation. But lets first look at the boring code

public bool UpdateStatus(string status)
{
string response;
List<QueryParameter> parameters = new List<QueryParameter>();
parameters.Add(new QueryParameter(OAuthUtility.StatusKey, status));
parameters.Add(new QueryParameter(OAuthUtility.VerifierKey, _accessToken.PIN));
try
{
response = CallTwitterPostMethod("statuses/update.xml", parameters);
}
catch (Exception ex)
{
HandleException(ex);
return false;
}
return true;
}

 

Nothing impressive here… Let’s go on…

The CallTwitterPostMethod is a little different than the previous one. It still starts out by getting a signed URL by calling the GetSignedUrl method, but after that it changes… It starts by stripping out the querystring part of the URL. This will be posted instead of sent as querystring parameters. After that, it creates a new HttpWebRequest using the querystringless (is that even a word? I think not, but I guess you know what I mean…) URL. And this method also ups the Timeout a bit and sets the Method. In this case the Method is set to “POST”. It then proceeds with changing the content type. The post will be made using "application/x-www-form-urlencoded". The next line of code is a trick to get around a problem with the HttpWebRequest. For some reason it defaults to using a feature called Expect100Continue. This needs to be turned off. You can read more about it if you just Google the word Expect100Continue. Most or the returned sites will probably be about Twitter…

Next is sets the content length, gets the request stream and sends the querystring into the stream using a StreamWriter. It then gets the response and turns it into a string that is returned from the method.

private string CallTwitterPostMethod(string methodName, List<QueryParameter> parameters)
{
string url = GetSignedUrl(BASE_URL + methodName, parameters, "POST", _accessToken.Token, _accessToken.TokenSecret);

string queryString = new Uri(url).Query.Substring(1);

string baseUrl = url.Substring(0, url.IndexOf("?"));
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl);
req.Timeout = 10000;
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ServicePoint.Expect100Continue = false;
req.ContentLength = queryString.Length;
StreamWriter sw = new StreamWriter(req.GetRequestStream());
sw.Write(queryString);
sw.Close();
string response;
StreamReader sr = null;
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
sr = new StreamReader(resp.GetResponseStream());
response = sr.ReadToEnd();
}
finally
{
if (sr != null)
sr.Close();
}
return response;
}

That’s it! That’s the Twitter class with all its helpers. In the downloadable code that will be posted at the end of the series you will actually see a few more classes. A base class to help with a little Xml stuff and some Twitter specific exceptions. But I didn’t feel that they were needed in this already way too long blog post.

I hope you have enjoyed this first part. As always it turned out to be longer than it was supposed to, but I felt that a good understanding of the topic might actually help out a bit.

The goal is to cover the webservices in the next post, which will probably go up early next week. After that it will be the view models and finally some ugly UI. This time I have actually created a nice looking UI as well, but that will be in the downloadable code only, as it adds unnecessary complexity to the project.

So, stay tuned for more Twitter client information. If you have any questions or comments just post them as usual! (Not that anyone ever does…or at least very few…).

Since I have a busy schedule at work at the moment, I’m not sure when the future posts will go up. I will try to get them online as soon as possible. But I would recommend subscribing to my RSS feed to get notified when they do go up…

Cheers!

PS: There is a serious lack of safety checks in the code…it is only demo. If you mean to use it, you should add checks making sure the correct values are passed to methods and so on.

PPS: You might also want to track the amount of requests being sent to Twitter since they have limited some of the calls to 150 per hour. That might seem like a lot, but when testing and developing, it is consumed fantastically fast…

[UPDATE]

Part 2 is now available

as well as Part 3 and Part 4 and Part 5

Comments (19) -

I don't know what namespace that I must using in silverlight or does it have more assembly for add reference to. I get many error in silverlight project. For example,

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = 10000;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

The System.Net.HttpWebRequest in silverlight 4.0 doesn't has Timeout property and GetResponse method.

It's good to give some details about using namespace, silverlight version, and may post some project solution to download Smile

Thanks a lot for your share.

Hi Noppol!
THat s very true. My code is not built for Silverlight 4, but for 3. The Timeout doesn't really matter that much, and the GetResponse() needs to be changed to BeginGetResponse()
Cheers!

i dint find this OAuthUtility class from where i will get it ... is it possible to give a souce code for this

Hi Amith!
The source code for this project is available at the end of the last post in the series. Just keep reading... Smile

hey, thanks a lot for this really great, thorough tutorial.  One question though.  
You suggested using BeginGetResponse() if we're using Silverlight 4.  The only problem with that is that begins an Async call.  Would the response reading have to be done in a Async callback after BeginGetResponse() finishes?  And in that case, how could you get your CallTwitterGetMethod to return a string if the reading is being done in a callback method?
Thanks.

Hi SW!
You are very correct. Switching to BeginGetResponse() would require some changes as it is async. You would have to do the parsing in the Completed event, and therefore would not be able to return string. So I would suggest changing the signature of the CallTwitterMethod() to return void and then add an Action<string> callback parameter at the end... Makes sense?
Cheers!

Hi Chris!
First of all, thanks for great application (also, with "real" design) and related blog series.

I am playing around with your application, and want to make some minor changes...one of them is mouse wheel support in ListBox with tweets in TimelineControl(scrolling).

I've already seen couple of solutions for SL3, but I also know that it is supported out of the box in SL4. And I was expecting it will just work when I change Target Silverlight Version setting in SilverTweet project properties and build solution, but it doesn't make any effect. I am new to Silverlight, and my naïve assumption is maybe parent SpeakBubble control somehow causes that...
Maybe you know what I am missing?

Hi Slava!
Updating to Silverlight 4 will change the way that it is compiled. If it isn't working, it might be because the listbox has been restyled. And having it restyled means having the control use custom XAML. That might cause newer features to fail. So my suggestion would be to try removing the custom styles and see if it works then...

Hi Chris!
Yes, thanks, it is something with custom styles, I removed them all, and scrolling works. But then I will add them back gradually to make it looks good and try to identify when it fails.

Hi again,
It is strange, but when I deleted ItemTemplate, Template, ItemContainerStyle properties from ListBox and then added them one by one to test, then it works now with the same xaml...
Anyway, good it works. And thanks again for this app.

Very nice articles

Sir,

I cannot logout the SilverTweet (means once logged on. I cant logout)

What changes should I do??

Reply Soon!

Hi Devesh!
That functionality has not been implemented. It should be fairly easy to do though.
It's been a while since I built this, but I guess the access token is stored in isolated storage. If you remove this and restart the app you should be done...
Cheers!

Wow thx a lot!!!
Before it I only found C# library that I was translating into silverlight one, but they also provide oauth provider, and I only need a consummer Laughing I'm not using it with twitter, and I have to use silverlight 4, but with all your job it's pretty easy =D
if you're agree I'll quote your article in my plugin description ;)

Hi Julien!
You are more than welcome to use my code, but I would obviously love it if you quoted my blog if it helped you...
You might need to tweak the code though, as it doesn't seem to play 100% nice with all OAuth providers. I don't know why... So remember to check against the provider that you are using...
Cheers!

juliendangers 1/25/2011 9:52:56 AM

I have to modify the post function, because I'm working with an elevated trust application, so I can execute real POST operations. I'm trying to modify the header (authorization).
No worry I'll will adapt it to my provider ;)
And be sure I'll quote your blog!

Hello Sir,
Nice project.
one question to you.
Is it possible to use Korean characters in your project?
I mean tweet in korean.
I tried, but nothing happened.
tweet in english is ok.
thanks.

If i want to run this application out of browsing ?how

Great post!  Found it really useful...

Just wanted to mention, your OAuthUrlEncode method doesn't account for already encoded characters so you end up escaping escape characters.  This isn't a problem with the Twitter provider, but Google likes to put "/" in their tokens.  

-Kyle

Comments are closed