Click here to Skip to main content
15,883,767 members
Articles / Web Development / ASP.NET

Tweeting through the Genesis Smart Client Framework

Rate me:
Please Sign up or sign in to vote.
4.90/5 (6 votes)
26 Apr 2010Ms-PL14 min read 21K   9  
This article demonstrates a basic Twitter client as a Genesis Hosted Application for the Genesis Smart Client Framework

Introduction

The Genesis Smart Client Framework was developed by Blue Marble, a South African software development house. The framework was developed as the means of distributing an application to a large wide-spread audience over the internet.

By providing a Dynamic Application Workspace the framework allowed the development team to focus on developing task specific modules, while the framework dealt with keeping client software up to date with the latest version of the modules, and provided users access to modules they were allowed to work with.

This article is a step-by-step guide for writing a Twitter client application. It continues where the Getting Started article left off. If you have not read this article yet, please do so now.

In the previous article you were introduced to the steps required to get the latest build of the Genesis Smart Client Framework running on your computer. You also learnt how to get the Template Application configured and runnning. In this article you will learn to enhance the Template Application to include a simple Twitter client. This client will use an existing C# Twitter library (LinqToTwitter, see below).

Why Twitter?

I decided to use Twitter as a generic application type to demonstrate the features of the Genesis Smart Client Framework. Using Twitter you will not be distracted by other unrelated features and concepts. Everybody knows that you can only send a status update to twitter, and read your twitter feed. We will ignore advanced features such as retweeting, user profiles etc.

I have never written a Twitter client before, so this will also be a first for me to develop using the Twitter API. Since this is my first attempt at a Twitter client, I did some research, and decided to settle for LINQToTwitter (http://linqtotwitter.codeplex.com/) as the preferred library to use.

Preparing the project

The LinqToTwitter library supports OpenAuth (OAuth) and we will use this as the default authentication mechanism. This will cause Twitter to prompt the user via an Internet browser if he/she is using the program. The user will be given a Verification PIN which we capture from the application.

Register an account with Twitter at http://dev.twitter.com/apps/new to get your Consumer Key and Consumer Secret. These values are used to uniquely identify your application when transacting with Twitter. You will need to enter these values in the correct places in the Constants file below.

I have created a new static class called Constants in the Genesis.Application project. This class contains some constant string values, including OAuthConsumerKey, OAuthConsumerSecret, the Request Token URL, Access Token URL and the Authorize URL. You HAVE to update these values with the values that you get from the registration of your application with Twitter on the URL above.

Constants
C#
namespace Genesis.Application
{
    public static class Constants
    {
        public const string OAuthConsumerKey = "YOURCONSUMERKEY";
        public const string OAuthConsumerSecret = "YOURCONSUMERSECRET";
        public const string OAuthRequestTokenURL = "https://api.twitter.com/oauth/request_token";
        public const string OAuthAccessTokenURL = "https://api.twitter.com/oauth/access_token";
        public const string OAuthAuthorizeURL = "https://api.twitter.com/oauth/authorize";
    }
}

Next you have to include a reference to the LinqToTwitter library in the Genesis.Application project. You can find this file in the download of the LinqToTwitter library from CodePlex. In order to use this library you have to change the <startup> tag in the app.config file for the BlueMarble.Genesis.Client project to <startup useLegacyV2RuntimeActivationPolicy="true">. I have included a Microsoft.NET 4.0 build of this library in the $/Stable/Stable Assemblies folder in the online source control at CodePlex.

References

To initialize the LinqToTwitter library we need to create a GlobalDataSetFunctionsInitializer implementation in the Genesis.Application project. The GlobalDataSetFunctionsInitializer is used by Genesis Hosted Applications that require initialization code to be executed during the startup of the application. The Client Application will identify any classes that implement the Genesis.Common.Interfaces.IGlobalDataSetFunctionsInitializer interface and automatically execute them before displaying the main form. In the GlobalDataSetFunctionsInitializer we will create a new ITwitterAuthorization and set the ConsumerKey and ConsumerSecret using the string constant values that we created.

C#
public void Initialize(Common.Classes.GlobalDataSetFunctions GlobalDataSetFunctions)
{
    Globals.auth = new DesktopOAuthAuthorization();

    (Globals.auth as DesktopOAuthAuthorization).ConsumerKey = Genesis.Application.Constants.OAuthConsumerKey;
    (Globals.auth as DesktopOAuthAuthorization).ConsumerSecret = Genesis.Application.Constants.OAuthConsumerSecret;

    Globals.auth.UseCompression = false;
    Globals.auth.UserAgent = "Genesis Template Application";
}

private string VerifierString()
{
    return Genesis.Application.Forms.Verifier.GetVerificationPin();
}

I have also created a Globals.cs class to contain the ITwitterAuthorization in a static class. This class will ensure that the LinqToTwitterWrapper is in shared memory. Not all applications will use global static classes, however I believe that dealing with the Twitter API it would be best to keep performance and resources in mind. I have also created a LinqToTwitterWrapper.cs which exposes static methods to deal with the Globals class. The wrapper acts as the Controller in a typical Model-View-Controller configuration.

C#
public static class Globals
{
    public static ITwitterAuthorization auth;
}
C#
public static class LinqToTwitterWrapper
    {
        public static TwitterContext twitterCtx = new TwitterContext(Globals.auth, "https://api.twitter.com/1/", "http://search.twitter.com/");

        public static void SignOn()
        {
            if (twitterCtx.AuthorizedClient is OAuthAuthorization)
            {
                InitializeOAuthConsumerStrings(twitterCtx);
            }

            try
            {
                Globals.auth.SignOn();
            }
            catch (OperationCanceledException)
            {
                return;
            }
        }

        private static void InitializeOAuthConsumerStrings(TwitterContext twitterCtx)
        {
            var oauth = (DesktopOAuthAuthorization)twitterCtx.AuthorizedClient;
            oauth.GetVerifier = () =>
            {
                return Genesis.Application.Forms.Verifier.GetVerificationPin();
            };

            if (oauth.CachedCredentialsAvailable)
            {
                Console.WriteLine("Skipping OAuth authorization step because that has already been done.");
            }
        }
    }

Because of how this implementation of the Twitter API using LinqToTwitter and OAuth works, we will rely on Twitter to provide us with an OAuth authentication token. This will happen automatically because an Internet browser will open asking the user to log in, or to confirm that the application is allowed to access the Twitter API using the users' credentials. The Twitter site will then provide the user with a Verification PIN which needs to be provided to the application. The following screen is used to capture the Verification PIN from the user, and is displayed during the authentication process.

References

During the sample we will continue to add more code to the classes above. We are now ready to move on to the next step.

Creating a User Interface

In this section we will create a form to display Tweets and the command to show the form. The form is going to be very simple and straight forward by using a ListBox to show the individual tweets and a textbox to allow the user to send a Tweet.

Tweetform

In order to make the form usable through the Genesis Smart Client Framework, we have to change the default inherited class from Form to Genesis.Client.Common.Classes.MdiChildBase and also to include the Genesis.Common.Interfaces.IMdiChild interface.

Tweetform
C#
public partial class TweetForm : Genesis.Client.Common.Classes.MdiChildBase, Genesis.Common.Interfaces.IMdiChild
{
    public TweetForm()
    {
        InitializeComponent();

Next you have to create the Command to allow Genesis to load the form in the User Interface. This is a class that inherits from Genesis.Common.Classes.CommandBase and implements the Genesis.Common.Interfaces.ICommand interface. This class has an Execute method which executes the code it contains. Genesis will ensure that the user has the correct security rights before it allows execution of this code.

C#
[Genesis.Common.Attributes.CommandCode("Genesis.Application.Commands.ShowTweetForm")]
[Genesis.Common.Attributes.CommandDescription("This command shows the tweet form")]
[Genesis.Common.Attributes.CommandName("Twitter Form")]
public class ShowTweetForm : Genesis.Common.Classes.CommandBase, Genesis.Common.Interfaces.ICommand
{
    #region ICommand Members

    void Genesis.Common.Interfaces.ICommand.Execute()
    {
        Genesis.Application.Forms.TweetForm tweetForm = new Genesis.Application.Forms.TweetForm();

        tweetForm.Host = base.host;

        base.host.CreateWindow(tweetForm);
    }

    #endregion
}

The code above is simple and self-descriptive, starting with the Attributes applied to the ShowTweetForm class:

  • CommandCode - The command code is a unique reference to this Command and is used by the Genesis Smart Client Framework to identify the correct class to execute. It is also used by the Update.aspx page in the Genesis.FileHost project to identify new Commands and to update existing Commands. For code maintenance reasons, it is simpler to keep the command code the same as the full namespace and classname. It is not limited to being the same as the full namespace and classname.
  • CommandDescription - The command description contains a description of the command.
  • CommandName - The command name contains an easy name for the command.

Looking at the class you will see that it only contains one method called Execute and that it does not require any parameters. In this implementation we see three lines of code. The first line creates a new copy of the TweetForm. The second line sets the Host property on the form. This property is available because of the interface that we implemented on the form. By passing the Host to the form, we are enabling the form to integrate directly with the main form of the BlueMarble.Genesis.Client application. The main form implements the global::Genesis.Common.Interfaces.IHost.

The third line of code accesses the Host property on the Command and instructs the main form to create a new window by calling the CreateWindow method.

We have written all the code we need to for now, in the next step we will configure the Genesis Smart Client Framework to identify the new Command and to set the security.

Configuring Genesis

The first step to configuring the new Command is to change the current version number for the application and then to recompile the application. Change the AssemblyVersion and AssemblyFileVersion attributes in the AssemblyInfo.cs file to any other version number. The actual number is unimportant, Genesis never expects a version to be higher/lower than the existing entries in the database. Genesis will respond if the version number has changed in any way.

I have set my version information to:

C#
[assembly: AssemblyVersion("1.0.1.1")]
[assembly: AssemblyFileVersion("1.0.1.1")]

Once you have done this, rebuild the project output and wait for the Update.ASPX page to complete its execution. Once you recompile the Update.aspx page should automatically open indicating that the project output has changed.

UpdateOutput

Once the update process has run, you will notice that Genesis has identified the new version number as 1.0.1.1 and that it also added a reference to the Genesis.Application.Commands.ShowTweetForm Command.

You can now run the application and sign into the Genesis Management System 2010 application.

Commands

Once you are signed into the Genesis Management System 2010, open the Genesis Administration menu and click on the Commands menu item. This will open the Commands screen. Look for the Genesis.Application.Commands.ShowTweetForm command and open its editor. Scroll down to the Group Membership section of the form and add the Registered Users and Genesis Application Users roles to this Command.

CommandRoles

This will enable users who are members of these roles to execute the Command. Next open the Genesis Administration menu and click on the Item menu item. We are going to create the menu item that will open this form. Create a new Bar Item by clicking on the Create Bar Item icon in the top right corner of the page.

Enter the following information into the provided fields:

  • Bar Name - Tweets
  • Parent Bar Item - <Root Item>
  • Bar Item Type - Button Item
  • Ribbon Bar - Seperator 1
  • Command - Twitter Form
  • Image - Select any image from the list, and enter 16 in the Size value.
  • Order - 200

Files

This application is referencing the LinqToTwitter.DLL library. Because the Genesis Client Application downloads only the files configured per application in Genesis, we also have to add this library to the configuration to ensure that it exists on the client when the Client Application executes your Genesis Hosted Application. Open on the Genesis Administration menu and click on the Files menu item.

Enter the following information into the provided fields:

  • File Name - LinqToTwitter.dll
  • Type - LinqToTwitter Library.
  • Description - LinqToTwitter library eases the use of the Twitter API.
  • Application - My First Genesis Application.
  • Order - 200.
  • Path - ..\..\Genesis Smart Framework\Genesis.Client.Host\bin\debug\
  • Url - http://localhost:1581/genesis.filehost/myapp/libraries/LinqToTwitter.dllx
  • Version - 1.0.0.0

The LinqToTwitter.DLL library has references to some other libraries (also available in the LinqToTwitter download and in $/Stable/Stable Assemblies in the CodePlex online source control) and these libraries have to be included in the list along with the LinqToTwitter.DLL. These files are:

  • DotNetOpenAuth.dll
  • System.Web.Mvc.dll
  • log4net.dll
  • Kerr.Credentials.dll

You can now sign out of the Genesis Management System 2010. Update the version number Attributes in the Genesis.Application project and rerun your application. You should now see entries for each of the new files on the output from the Update.ASPX page in the Genesis.FileHost website.

I have set my version information to:

C#
[assembly: AssemblyVersion("1.0.1.2")]
[assembly: AssemblyFileVersion("1.0.1.2")]

Once you have changed your version information you can rebuild the solution, and the files should now be visible in the output from the Update.ASPX page.

File
File
File

If you followed the steps detailed in the previous article you should have an application called My First Genesis Application

Once you are signed into your own application you should notice a new menu item in the My First Menu menu called Tweets. This menu is visible because you added it to the configuration earlier, and because your user is a member of one or more of the groups that were added to the Genesis.Application.Commands.ShowTweetForm Command.

Tweets

Click on this menu to open the Tweet Form. The image below is slightly cropped, to the right of the image there is simply a 'Tweet!' button and then the end of the form. This form was added to the main form because the main form implements the IHost interface. This interface allows the Commands, and child windows to communicate with the main form to instruct it to open/close forms, update the status bar text, create/remove menu's and menu items.

TweetForm

We can now focus on adding functionality to the form since we have done everything that the Genesis Smart Client Framework requires. REMEMBER: Each time we want to debug and test new features or fixes we simply have to change the AssemblyVersion and AssemblyFileVersion attributes.

Making it Tweet

In this section we will link up the Tweet Form to the Twitter API via LinqToTwitter. You will write a Linq query to select all of the users' Tweets from his/her followers or themselves. You will also allow the user to update his/her status by sending a Tweet.

The first step was to add a method to the LinqToTwitterWrapper class to expose the Twitter public feed to our application. This method selects all of the tweets whose type is either a Public tweet, or a tweet from Friends. It also sorts the tweets so that the newest always appears first in the list.

C#
public static LinqToTwitter.TwitterQueryable<LinqToTwitter.Status> GetPublicTweets()
{
    var tweets =
        from tweet in twitterCtx.Status
        where tweet.Type == (Globals.auth.CachedCredentialsAvailable ? StatusType.Friends : StatusType.Public)
        orderby tweet.CreatedAt ascending
        select tweet;

    return (LinqToTwitter.TwitterQueryable<LinqToTwitter.Status>)tweets;
}

The we are going to link up our Tweet Form to process this feed and to display the results in the List Box. Add a Timer control to the Tweet Form and set the Interval to 60000 (one minute). Next make sure that your code behind looks like this:

C#
public partial class TweetForm : Genesis.Client.Common.Classes.MdiChildBase, Genesis.Common.Interfaces.IMdiChild
{
    public TweetForm()
    {
        InitializeComponent();

        LinqToTwitterWrapper.SignOn();
    }

    private void tweemer_Tick(object sender, EventArgs e) 
    { 
        tweemer.Enabled = false;

        LinqToTwitter.TwitterQueryable <linqtotwitter.status> statusTweets = LinqToTwitterWrapper.GetPublicTweets();

        foreach (LinqToTwitter.Status status in statusTweets)
        {
            string tweet = string.Empty;

            tweet = string.Format("{0} said {1} - {2} ago",
                status.User.Name,
                status.Text,
                GetTweetTime(status));

            if (!tweets.Items.Contains(tweet))
                tweets.Items.Insert(0, tweet);
        }

        tweemer.Enabled = true;
    }

    private static string GetTweetTime(LinqToTwitter.Status status)
    {
        TimeSpan tweetTime = new TimeSpan(DateTime.Now.Ticks - status.CreatedAt.Ticks);

        string returnValue = string.Empty;

        if (tweetTime.TotalSeconds < 60)
        {
            returnValue = string.Format("{0} seconds ago",
                tweetTime.TotalSeconds);
        }
        else if (tweetTime.TotalMinutes < 60)
        {
            returnValue = string.Format("{0} minutes ago",
                tweetTime.TotalMinutes);
        }
        else if (tweetTime.TotalHours < 24)
        {
            returnValue = string.Format("{0} hours ago",
                tweetTime.TotalHours);
        }
        else
        {
            returnValue = string.Format("{0} days ago",
                tweetTime.TotalDays);
        }

        return returnValue;
    }
}

You are now ready to run the application and access your tweets. Update the version number Attributes in the Genesis.Application project and rerun your application. You should now see entries for each of the new files on the output from the Update.ASPX page in the Genesis.FileHost website.

I have set my version information to:

C#
[assembly: AssemblyVersion("1.0.1.3")]
[assembly: AssemblyFileVersion("1.0.1.3")]

Tweeting

Run the application and log into My First Genesis Application. Open the My First Menu menu and click on the Tweets menu item. The first time that you do this, your Internet browser should open automatically to confirm if this application is allowed to access your tweets.

Verification

Click Allow to get the Verification PIN. You will need to copy this PIN so that you can provide it to the Twitter client for authentication.

Verification

Enter the Verification PIN into the space provided on the Verification PIN form in the application. This PIN will be provided to the OAuth provider and only has to be done once. The authentication token is cached until such a time as the user reboots his/her computer, or if the user is inactive for a sufficient amount of time.

Verification

Your tweets should now be visible in the list box as below. The format of the output in the listbox is "{USER} said {TWEET} - {TIMESTAMP}". In the image below you will notice some highlighted areas indicating the USER, TWEET and TIMESTAMP fields.

Tweets

The next step will be to allow the user to send their Tweets. To do this, add the following code to the tweetton (thats the name of the 'Tweet!' button):

C#
 LinqToTwitterWrapper.UpdateStatus(tweetBox.Text);
tweetBox.Text = string.Empty;

tweemer_Tick(sender, e);

This code will use the LinqToTwitterWrapper to execute the UpdateStatus method, then it will clear the tweetBox (thats the name of the status textbox) and execute the tweemer_Tick event (tweemer is the name of the Twitter timer)

Add the following code to the LinqToTwitterWrapper:

C#
public static void UpdateStatus(string Tweet)
{
    twitterCtx.UpdateStatus(Tweet);
}

This code will execute the UpdateStatus method on the TwitterContext static field. The Tweet is passed in as a parameter.

Update the version number Attributes in the Genesis.Application project and rerun your application. You should now see entries for each of the new files on the output from the Update.ASPX page in the Genesis.FileHost website.

I have set my version information to:

C#
[assembly: AssemblyVersion("1.0.1.4")]
[assembly: AssemblyFileVersion("1.0.1.4")]

As soon as you have been authenticated open the My First Menu menu and click on the Tweets menu item. Enter some text into the TweetBox and click the 'Tweet!' button.

Tweets

You should see your tweet appear in the listbox below. See the highlighted regions of the image.

Tweets

And finally if you sign directly into your Twitter page or any other Twitter client you will see your posts appear there as well.

Tweets

Thats it, you have successfully written a Twitter client on the Genesis Smart Client Framework. Each time you update your application, your users will automatically get those same updates.

Other information

Blue Marble is proud to be a Microsoft BizSpark startup company. Image 20

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
We Fix Code
South Africa South Africa
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --