65.9K
CodeProject 正在变化。 阅读更多。
Home

通过 Genesis Smart Client Framework 发推

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (6投票s)

2010 年 4 月 24 日

Ms-PL

14分钟阅读

viewsIcon

21693

本文演示了一个作为 Genesis Hosted Application 的基本 Twitter 客户端,用于 Genesis Smart Client Framework。

引言

Genesis Smart Client Framework 由 Blue Marble 开发,这是一家南非的软件开发公司。该框架被开发为通过互联网向广大用户分发应用程序的手段。

通过提供动态应用程序工作区,该框架允许开发团队专注于开发任务特定模块,而框架则负责保持客户端软件与最新模块版本的同步,并为用户提供访问他们被允许使用的模块的权限。

本文是编写 Twitter 客户端应用程序的分步指南。它承接了入门文章的内容。如果您尚未阅读这篇文章,请立即阅读。

在上一篇文章中,您了解了在计算机上运行 Genesis Smart Client Framework 的最新版本所需的步骤。您还学习了如何配置和运行模板应用程序。在本文中,您将学习如何增强模板应用程序以包含一个简单的 Twitter 客户端。此客户端将使用现有的 C# Twitter 库(LinqToTwitter,见下文)。

为什么选择 Twitter?

我决定使用 Twitter 作为通用应用程序类型来演示 Genesis Smart Client Framework 的功能。使用 Twitter,您将不会被其他无关的功能和概念所分心。大家都知道,您只能向 Twitter 发送状态更新,并读取您的 Twitter 动态。我们将忽略诸如转推、用户配置文件等高级功能。

我以前从未写过 Twitter 客户端,所以这也是我第一次尝试使用 Twitter API 进行开发。由于这是我第一次尝试制作 Twitter 客户端,我做了一些研究,并决定选择 LINQToTwitter(http://linqtotwitter.codeplex.com/)作为首选库。

准备项目

LinqToTwitter 库支持 OpenAuth (OAuth),我们将使用它作为默认身份验证机制。这将导致 Twitter 在用户使用该程序时通过 Internet 浏览器提示用户。用户将获得一个验证 PIN 码,我们将其从应用程序中捕获。

http://dev.twitter.com/apps/new 注册一个 Twitter 账户,以获取您的 Consumer Key 和 Consumer Secret。这些值用于在与 Twitter 进行交易时唯一标识您的应用程序。您需要在下面的 Constants 文件中的正确位置输入这些值。

我在 Genesis.Application 项目中创建了一个新的静态类,名为 Constants。该类包含一些常量字符串值,包括 OAuthConsumerKey、OAuthConsumerSecret、Request Token URL、Access Token URL 和 Authorize URL。您必须使用您在上述 URL 上注册应用程序后获得的这些值来更新它们。

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

接下来,您必须在 Genesis.Application 项目中包含对 LinqToTwitter 库的引用。您可以在 CodePlex 的 LinqToTwitter 库下载中找到此文件。为了使用此库,您必须更改 BlueMarble.Genesis.Client 项目的 app.config 文件中的 <startup> 标记为 <startup useLegacyV2RuntimeActivationPolicy="true">。我已将此库的 Microsoft.NET 4.0 版本包含在 CodePlex 的在线源代码控件的 $/Stable/Stable Assemblies 文件夹中。

References

为了初始化 LinqToTwitter 库,我们需要在 Genesis.Application 项目中创建一个 GlobalDataSetFunctionsInitializer 实现。GlobalDataSetFunctionsInitializer 用于需要初始化代码在应用程序启动时执行的 Genesis 托管应用程序。客户端应用程序将识别任何实现 Genesis.Common.Interfaces.IGlobalDataSetFunctionsInitializer 接口的类,并在显示主窗体之前自动执行它们。在 GlobalDataSetFunctionsInitializer 中,我们将创建一个新的 ITwitterAuthorization 并使用我们创建的字符串常量值设置 ConsumerKey 和 ConsumerSecret。

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

我还创建了一个 Globals.cs 类来包含 ITwitterAuthorization 的静态类。该类将确保 LinqToTwitterWrapper 位于共享内存中。并非所有应用程序都会使用全局静态类,但我认为在使用 Twitter API 时,应考虑性能和资源。我还创建了一个 LinqToTwitterWrapper.cs,它公开了用于处理 Globals 类的静态方法。该包装器充当典型 Model-View-Controller 配置中的 Controller。

public static class Globals
{
    public static ITwitterAuthorization auth;
}
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.");
            }
        }
    }

由于 LinqToTwitter 和 OAuth 实现 Twitter API 的方式,我们将依赖 Twitter 为我们提供 OAuth 身份验证令牌。这会自动发生,因为 Internet 浏览器会打开并要求用户登录,或确认应用程序是否允许使用用户的凭据访问 Twitter API。然后,Twitter 网站将为用户提供一个验证 PIN 码,该 PIN 码需要提供给应用程序。以下屏幕用于捕获用户的验证 PIN 码,并在身份验证过程中显示。

References

在示例中,我们将继续向上述类添加更多代码。现在我们已准备好进入下一步。

创建用户界面

在本节中,我们将创建一个窗体来显示 Tweets 以及显示该窗体的命令。该窗体将非常简单明了,使用 ListBox 显示 individual tweets,并使用 textbox 允许用户发送 Tweet。

Tweetform

为了使窗体能够通过 Genesis Smart Client Framework 使用,我们必须将默认的继承类从 Form 更改为 Genesis.Client.Common.Classes.MdiChildBase,并包含 Genesis.Common.Interfaces.IMdiChild 接口。

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

接下来,您必须创建 Command 来允许 Genesis 加载用户界面中的窗体。这是一个继承自 Genesis.Common.Classes.CommandBase 并实现 Genesis.Common.Interfaces.ICommand 接口的类。该类有一个 Execute 方法,用于执行其中包含的代码。Genesis 将确保用户拥有正确的安全权限,然后才允许执行此代码。

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

上面的代码简单且自解释,从应用于 ShowTweetForm 类的 Attributes 开始

  • CommandCode - 命令代码是此命令的唯一引用,Genesis Smart Client Framework 使用它来标识要执行的正确类。Genesis.FileHost 项目中的 Update.aspx 页面也使用它来标识新命令并更新现有命令。出于代码维护原因,将命令代码与完整的命名空间和类名保持一致会更简单。它不限于与完整的命名空间和类名相同。
  • CommandDescription - 命令描述包含对命令的描述。
  • CommandName - 命令名称包含命令的易记名称。

查看该类,您会发现它只有一个名为 Execute 的方法,并且不需要任何参数。在此实现中,我们看到三行代码。第一行创建了一个 TweetForm 的新副本。第二行设置了窗体上的 Host 属性。由于我们实现的接口,该属性可用。通过将 Host 传递给窗体,我们使窗体能够直接与 BlueMarble.Genesis.Client 应用程序的主窗体集成。主窗体实现了 global::Genesis.Common.Interfaces.IHost

第三行代码访问 Command 上的 Host 属性,并通过调用 CreateWindow 方法指示主窗体创建一个新窗口。

目前我们已经编写了所有必要的代码,下一步我们将配置 Genesis Smart Client Framework 来识别新的 Command 并设置安全性。

配置 Genesis

配置新 Command 的第一步是更改应用程序的当前版本号,然后重新编译应用程序。在 AssemblyInfo.cs 文件中将 AssemblyVersionAssemblyFileVersion 属性更改为任何其他版本号。实际数字不重要,Genesis 从不期望版本高于/低于数据库中的现有条目。如果版本号有任何变化,Genesis 都会做出响应。

我已将我的版本信息设置为

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

完成此操作后,重建项目输出,等待 Update.ASPX 页面完成执行。一旦您重新编译,Update.aspx 页面应自动打开,指示项目输出已更改。

UpdateOutput

更新过程运行后,您会注意到 Genesis 已识别新版本号为 1.0.1.1,并且它还添加了对 Genesis.Application.Commands.ShowTweetForm 命令的引用。

您现在可以运行应用程序并登录 Genesis Management System 2010 应用程序。

Commands

登录 Genesis Management System 2010 后,打开 Genesis Administration 菜单,然后单击 Commands 菜单项。这将打开 Commands 屏幕。查找 Genesis.Application.Commands.ShowTweetForm 命令并打开其编辑器。向下滚动到表单的 Group Membership 部分,并将 Registered UsersGenesis Application Users 角色添加到此 Command。

CommandRoles

这将使用户能够执行该 Command。接下来,打开 Genesis Administration 菜单,然后单击 Item 菜单项。我们将创建将打开此窗体的菜单项。通过单击页面右上角的 Create Bar Item 图标来创建一个新的 Bar Item。

在提供的字段中输入以下信息

  • Bar Name - Tweets
  • Parent Bar Item - <Root Item>
  • Bar Item Type - Button Item
  • Ribbon Bar - Seperator 1
  • Command - Twitter Form
  • Image - 从列表中选择任何图像,并在 Size 值中输入 16
  • Order - 200

文件

此应用程序引用了 LinqToTwitter.DLL 库。由于 Genesis Client Application 仅下载 Genesis 中为每个应用程序配置的文件,因此我们也必须将此库添加到配置中,以确保在 Client Application 执行您的 Genesis Hosted Application 时该库存在。在 Genesis Administration 菜单上,单击 Files 菜单项。

在提供的字段中输入以下信息

  • File Name - LinqToTwitter.dll
  • Type - LinqToTwitter Library。
  • Description - LinqToTwitter 库简化了 Twitter API 的使用。
  • Application - My First Genesis Application
  • Order - 200.
  • Path - ..\..\Genesis Smart Framework\Genesis.Client.Host\bin\debug\
  • Url - https://:1581/genesis.filehost/myapp/libraries/LinqToTwitter.dllx
  • 版本 - 1.0.0.0

LinqToTwitter.DLL 库引用了其他一些库(也包含在 LinqToTwitter 下载和 CodePlex 在线源代码控件的 $/Stable/Stable Assemblies 中),这些库必须与 LinqToTwitter.DLL 一起包含在此列表中。这些文件是

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

您现在可以退出 Genesis Management System 2010。更新 Genesis.Application 项目中的版本号 Attributes 并重新运行您的应用程序。您现在应该在 Genesis.FileHost 网站的 Update.ASPX 页面的输出中看到新文件的条目。

我已将我的版本信息设置为

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

更改版本信息后,您可以重新生成解决方案,文件现在应该会显示在 Update.ASPX 页面的输出中。

File
File
File

如果您遵循上一篇文章中详细介绍的步骤,您应该会有一个名为 My First Genesis Application 的应用程序。

登录您自己的应用程序后,您应该会注意到 My First Menu 菜单中有一个名为 Tweets 的新菜单项。此菜单可见是因为您之前已将其添加到配置中,并且您的用户是添加到 Genesis.Application.Commands.ShowTweetForm 命令的组之一或多个的成员。

Tweets

单击此菜单以打开 Tweet Form。下图略有裁剪,图像右侧仅有一个“Tweet!”按钮,然后是窗体的结尾。此窗体已添加到主窗体,因为主窗体实现了 IHost 接口。此接口允许 Command 和子窗口与主窗体通信,以指示其打开/关闭窗体、更新状态栏文本、创建/删除菜单项。

TweetForm

现在我们可以专注于为窗体添加功能,因为我们已经完成了 Genesis Smart Client Framework 所需的所有工作。请记住:每次我们要调试和测试新功能或修复时,我们只需更改 AssemblyVersionAssemblyFileVersion Attributes。

开始发推

在本节中,我们将通过 LinqToTwitter 将 Tweet Form 与 Twitter API 连接起来。您将编写一个 Linq 查询来选择用户关注者或用户自己的所有 Tweets。您还将允许用户通过发送 Tweet 来更新其状态。

第一步是在 LinqToTwitterWrapper 类中添加一个方法,将 Twitter 公共 Feed 暴露给我们的应用程序。此方法选择所有类型为 Public tweet 或 Friends tweet 的推文。它还会对推文进行排序,以便最新的始终显示在列表中。

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

然后,我们将链接我们的 Tweet Form 以处理此 Feed 并将结果显示在 List Box 中。向 Tweet Form 添加一个 Timer 控件,并将 Interval 设置为 60000(一分钟)。接下来,确保您的代码隐藏如下所示:

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

您现在可以运行应用程序并访问您的 Tweets。更新 Genesis.Application 项目中的版本号 Attributes 并重新运行您的应用程序。您现在应该在 Genesis.FileHost 网站的 Update.ASPX 页面的输出中看到新文件的条目。

我已将我的版本信息设置为

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

发推

运行应用程序并登录 My First Genesis Application。打开 My First Menu 菜单,然后单击 Tweets 菜单项。第一次执行此操作时,您的 Internet 浏览器应自动打开以确认是否允许此应用程序访问您的 Tweets。

Verification

单击 Allow 以获取验证 PIN 码。您需要复制此 PIN 码,以便将其提供给 Twitter 客户端进行身份验证。

Verification

在应用程序的验证 PIN 码窗体中提供的空间中输入验证 PIN 码。此 PIN 码将提供给 OAuth 提供商,并且只需要执行一次。身份验证令牌会被缓存,直到用户重新启动其计算机,或者用户长时间不活动为止。

Verification

您的 Tweets 现在应该显示在列表框中,如下所示。列表框中的输出格式为“{USER} said {TWEET} - {TIMESTAMP}”。在下面的图像中,您会注意到一些突出显示的区域,指示 USER、TWEET 和 TIMESTAMP 字段。

Tweets

下一步将允许用户发送他们的 Tweets。为此,请将以下代码添加到 tweetton(这是“Tweet!”按钮的名称)中:

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

tweemer_Tick(sender, e);

此代码将使用 LinqToTwitterWrapper 执行 UpdateStatus 方法,然后清除 tweetBox(这是状态文本框的名称)并执行 tweemer_Tick 事件(tweemer 是 Twitter 定时器的名称)。

将以下代码添加到 LinqToTwitterWrapper:

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

此代码将执行 TwitterContext 静态字段上的 UpdateStatus 方法。Tweet 作为参数传入。

更新 Genesis.Application 项目中的版本号 Attributes 并重新运行您的应用程序。您现在应该在 Genesis.FileHost 网站的 Update.ASPX 页面的输出中看到新文件的条目。

我已将我的版本信息设置为

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

成功进行身份验证后,打开 My First Menu 菜单,然后单击 Tweets 菜单项。在 TweetBox 中输入一些文本,然后单击“Tweet!”按钮。

Tweets

您应该会在下面的列表框中看到您的 tweet。请参见图像中的突出显示区域。

Tweets

最后,如果您直接登录到您的 Twitter 页面或任何其他 Twitter 客户端,您也会看到您的帖子出现在那里。

Tweets

好了,您已成功在 Genesis Smart Client Framework 上编写了一个 Twitter 客户端。每次更新您的应用程序时,您的用户都会自动获得相同的更新。

其他信息

Blue Marble 自豪地成为 Microsoft BizSpark 初创公司。

© . All rights reserved.