Welcome back! Or at least I hope it is welcome BACK. If you are not coming back, that means that you have missed the first part of this blog series. And in that case, I recommend by starting out by reading the first part. If you have already done that…let’s get cracking…
In the first part, I focused on the connection to Twitter. That included implementing OAuth and the Twitter methods I need to get the client to run. In this part, which will be a lot shorter, I’m going to focus on creating a webservice that can expose the Twitter functionality to the Silverlight client.
So the first step in doing this is to add a new Web Application project to the solution I am working on. So the solution now contains one Class Library project and one Web Application. To the Web Application project, I add a WCF service called TwitterService. Just remember that the WCF service must be Silverlight enabled. So choose the “Silverlight-enabled WCF Service project”. Otherwise it will not be possible to call it from a Silverlight client.
So what does the Silverlight-enabled service have that normal services don’t have. Well…the thing is this. Silverlight’s communication skills are still pretty limited. So when creating a Silverlight-enabled service makes sure that it can be called by this somewhat limited client. It includes setting up a binding type that Silverlight understands, and making sure that it runs in ASP.NET Compatibility mode. But I’m really not the person to educate on this topic, so I’ll just leave that and remember to use the correct project type.
Next I create a reference to my TwitterConnection project from my Web Application project. My service will expose the contents of this project, and thus must have a reference to it. After I have added my reference it is time to get started with the implementation. First things first. I rename the DoWork method that VS gives me to GetAuthorizationUrl. The method takes no parameters and returns an instance of a class called AuthorizationUrlResponse. I create this extra “response” class to be able to return multiple values. As you might recall, the GetAuthorizationUrl method in the TwitterConnection class returns both a URL and a AuthorizationToken. The actual class is very simple and looks like this
public class AuthorizationUrlResponse
{
public string Url { get; set; }
public AuthToken Token { get; set; }
}
Next up is the implementation of the method. This is very simple. Just get a reference to a TwitterConnection object, call its corresponding method and return the value. All the methods in the service will be this simple. There is no logic in the service at all, everything is in the TwitterConnection object.
[OperationContract]
public AuthorizationUrlResponse GetAuthorizationUrl()
{
Twitter twitter = GetTwitterConnection();
AuthToken token;
string url = twitter.GetAuthorizationUrl(out token);
return new AuthorizationUrlResponse() { Url = url, Token = token };
}
So there are two important things in this code. There is the OperationContract attribute. Without this, the method will not be considered a part of the webservice’s public interface. So don’t forget it… The other one is the GetTwitterConnection method. Since I will be getting references to this object over and over again, I have created two helper methods. They will help me initialize the TwitterConnection object, passing in the consumer key and consumer secret. Very simple…but makes the code a lot more readable. Or..hmm…maybe not a LOT more readable, but a little. And it also makes it easy for me to switch out the way that I store my consumer key and secret. For now, I have opted for the simple way of storing them in the web.config file in the appSettings section.
<appSettings>
<add key="consumerKey" value="xxxxxx"/>
<add key="consumerSecret" value="xxxxxx"/>
</appSettings>
This is quick and dirty, but works fine. These values will be used every single time I need a TwitterConnection object. And in all theauthenticated callse, I need to pass in an AccessToken as well. So I created these two little helpers
private Twitter GetTwitterConnection()
{
return new Twitter(WebConfigurationManager.AppSettings["consumerKey"], WebConfigurationManager.AppSettings["consumerSecret"]);
}
private Twitter GetTwitterConnection(AccessToken accessToken)
{
return new Twitter(WebConfigurationManager.AppSettings["consumerKey"], WebConfigurationManager.AppSettings["consumerSecret"],accessToken);
}
That is all that is needed for the GetAuthorizationUrl. As you will see very soon, all of these methods work like this. So making the TwitterConnection object and placing all the functionality in a structure way in it, makes the service layer very thin and simple.
The next step is the GetAccessToken method. This time, I can’t just rename an existing method, so I add a new one. It should take 2 parameters, the PIN code and an AuthToken. And yeah…don’t forget the OperationContract attribute
[OperationContract]
public AccessToken GetAccessToken(string pin, AuthToken authToken)
{
Twitter twitter = GetTwitterConnection();
return twitter.GetAccessToken(pin, authToken);
}
The rest of the methods all work like this, making it very easy, but repetitive to create them. So here they are
[OperationContract]
public bool Tweet(string text, AccessToken token)
{
Twitter twitter = GetTwitterConnection(token);
return twitter.UpdateStatus(text);
}
[OperationContract]
public User VerifyCredentials(AccessToken token)
{
Twitter twitter = GetTwitterConnection(token);
return twitter.VerifyCredentials();
}
[OperationContract]
public Tweet[] GetTimeline(AccessToken token, long? sinceId,int? count)
{
Twitter twitter = GetTwitterConnection(token);
return twitter.GetTimeline(sinceId, count);
}
That’s it for implementing the service. Let’s just make sure it works. To do this, I add a new Silverlight Application project to my solution. I name it SilverTweet of course… When clicking OK, a new dialog pops-up. VS wants to know how to host the Silverlight application. Since I already have Web Application project in the solution, VS assumes I want to use this and preselects for me. It also assumes that I want to have a test page to host the application and that I want to be able to debug it. Of course I do want all of that this time, so I click OK.
Next I right-click the References folder in the Solution Explorer and select Add Service Reference. In the dialog that pops-up I click the Discover. This will go through all the projects in the solution looking for services. It will of course only find one, the TwitterService.svc one. In the Namspace textbox, I type TwitterService and click OK. This will generate my proxy class for me and set up the bindings and all.
Most of the binding information will be stored in the ServiceReferences.ClientConfig file. So when you publish your service to its final location, you need to change the service address in there. However, closing down and opening up VS might cause your Web Application project to be using a different webserver port. This might cause issues if you need to refresh the proxy class after modifying the service. In that case, right-clicking the service reference and choosing Update Service Reference will fail. Just updating the ServiceReferences.ClientConfig will unfortunately not fix this. The address to the service is stored in a bunch of files created at the time of the service proxy creation. The simplest way is to just remove the reference and recreate it. Just remember to use the same name each time.
After having added the service reference, I take a look at the MainPage.xaml file. I just want to make sure that the service works as it should. So I add a Button and a TextBlock. To make it simple, I add them inside a StackPanel. I also hook up the Buttons click event to a handler. This is one of the better features when working with Xaml instead of ASP.NET. Intellisense helps me set up the handler even from markup. I love that…
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Click Me" HorizontalAlignment="Center" Click="Button_Click" />
<TextBlock x:Name="txt" HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</Grid>
The next step is to actually call the service. So I go to the code for the event handler. To move from markup to code is a simple F7 click… In the handler, I instantiate a new TwitterService.TwitterServiceClient instance. I hook up a handler for the GetAuthorizationUrlCompleted event. And finally I call the GetAuthorizationUrlAsync method.
The proxy class that VS created opts for a aync approach that I personally like a lot. Instead of having callbacks and IAsyncResult objects to finish off the async call, it uses events. So each method in the service will have a corresponding method and event in the proxy. The event will have a custom EventArgs class for handling the return value as well as errors. This makes it very simple to implement. And since all service calls are async in Silverlight, there is a lot of this going on. One can even implement the event handler as an anonymous method. Just remember that detach the handler when it has been called, so you don’t keep adding new handlers that will be called the next time you call a method. This can cause some serious problems. Is you go for anonymous methods, it can be a challenge to detach them. This can be solved by using this code
EventHandler<GetAuthorizationUrlCompletedEventArgs> handler = null;
handler = delegate(object o, GetAuthorizationUrlCompletedEventArgs ev)
{
client.GetAuthorizationUrlCompleted -= handler;
};
client.GetAuthorizationUrlCompleted += handler;
Just remember that you need to declare the handler variable before assigning it. Otherwise you wont have access to it and cannot detach it. And yeah…it needs to be declared as null, otherwise the compiler will complain and say that you are using an unassigned variable.
Anyhow…back to the service test. I went for the non anonymous method approach ending up with this code
private void Button_Click(object sender, RoutedEventArgs e)
{
TwitterService.TwitterServiceClient client = new SilverlightApplication2.TwitterService.TwitterServiceClient();
client.GetAuthorizationUrlCompleted += new EventHandler<SilverlightApplication2.TwitterService.GetAuthorizationUrlCompletedEventArgs>(client_GetAuthorizationUrlCompleted);
client.GetAuthorizationUrlAsync();
}
void client_GetAuthorizationUrlCompleted(object sender, SilverlightApplication2.TwitterService.GetAuthorizationUrlCompletedEventArgs e)
{
}
The handler gets a ridiculously simple implementation. Remember, it is just to test the service.
void client_GetAuthorizationUrlCompleted(object sender, SilverlightApplication2.TwitterService.GetAuthorizationUrlCompletedEventArgs e)
{
txt.Text = e.Result.Url;
}
So if I run this and click the Button, the TextBlock should show me the URL to the Twitter authorization page. I should of course used a HyperlinkButton for this, but I’m not actually going to click it, so who cares… Well, it worked for me…it gave me this, which looks quite correct.

If you want to, you could change the TextBlock into a HyperlinkButton just to verify that it works…
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Click Me" HorizontalAlignment="Center" Click="Button_Click" />
<HyperlinkButton x:Name="Hyperlink" TargetName="_blank"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
void client_GetAuthorizationUrlCompleted(object sender, GetAuthorizationUrlCompletedEventArgs e)
{
Hyperlink.NavigateUri = new Uri(e.Result.Url);
Hyperlink.Content = e.Result.Url;
}
Which should give you this

And if you click the link it should give you something that resembles this
That’s actually it for now. My goal was to cover the service layer in this post, and that I have done. It was a pretty short and uninteresting post as such, but that’s what you get for doing the preparation work well. I could have opted for the simple, but quite ugly, solution of having all of the logic in the service. But but separating it like I have done in this case, not only makes it easy to implement the service, but also makes it possible for me to use the TwitterConnection from for example a windows application. To be perfectly honest, while creating the TwitterConnection object, I actually did just that. I used a simple Windows Forms project to host my library so that I could test it out and make sure it worked. I personally like doing it this way, since starting debugging using the Windows Forms project is faster than using a Web Application project. It also gives me some pretty flexible controls to view the result I got from Twitter.
The last part of this whole thing is creating the actual Silverlight client for it. This involves a fair amount of things, and might not fit into one single post. So I would say that you are now only 2 posts away from having created your first Silverlight Twitter client.
If you have any questions or issues (with my post or code…any other issues should be dealt with in other ways…) or anything, just drop me a line or post a comment and I will get back to you.
Cheers!
[UPDATE]
Part 3 is now available and Part 4 and Part 5