發(fā)布日期: 10/27/2005 | 更新日期: 10/27/2005
Peter Bernhardt
3Leaf Development很多年以前,我得到一個經(jīng)驗:我不需要了解所有事情就能了解整個世界。當(dāng)然,得出這個結(jié)論本身就是一種自大的行為。但是這種自大源于年輕無知,現(xiàn)在我更清楚地認(rèn)識到了這一點。實際上,這個事實只有在 Internet 時代才被放大了,因為我發(fā)現(xiàn)我不可能跟上 Web 上永不停止的信息、思想和觀念流。甚至在我感興趣的領(lǐng)域,我也很難跟上 Visual Basic、Visual C# 和 .NET Framework 的最新發(fā)展。
因此,在接下來的幾個課程中,我將探索通過不同的方法來使用您很可能已經(jīng)熟悉的工具:RSS(即真正簡單的聯(lián)合發(fā)布系統(tǒng))- 一種能夠大大減輕信息超載現(xiàn)象的技術(shù)。
作為快速入門,Wikpedia 將 RSS 描述為:“對 Web 內(nèi)容的間斷介紹以及指向完整內(nèi)容的鏈接。此信息以 XML 文件的形式提供,稱為 RSS 源、webfeed、RSS 流或 RSS 通道。除了使聯(lián)合更方便以外,RSS 還使經(jīng)常訪問網(wǎng)站的讀者能夠使用新信息聯(lián)合器跟蹤該網(wǎng)站的更新。” [有關(guān)完整的信息,請參閱
RSS on Wikpedia(英文)。]
在開始以前,讓我們先來看一個可以使用 Visual Web Developer 2005 Express Edition 創(chuàng)建的簡單 RSS 源閱讀器。我將創(chuàng)建一個控件,從所需的站點中提取 RSS 源,并對該內(nèi)容進(jìn)行組織以顯示在網(wǎng)頁上。當(dāng)然,如果您是為了自己使用而聯(lián)合內(nèi)容,也可以創(chuàng)建 Windows 應(yīng)用程序形式的 RSS 源閱讀器,或者利用任何一個已有的免費 RSS 客戶端應(yīng)用程序 [例如,
RSS Reader(英文)或
SharpReader(英文)]。但是,在 Web 應(yīng)用程序中聯(lián)合內(nèi)容有其他目的 - 它使您能夠擴(kuò)展自己創(chuàng)建的內(nèi)容,并豐富了訪問您站點的用戶的體驗。
在涉及代碼之前,讓我們先看一小段典型的 RSS 2.0 文件內(nèi)容。在此示例中,聯(lián)合的提供程序為 Microsoft 的 MSDN 網(wǎng)站,并且我使用了 Visual Basic 內(nèi)容專用的 RSS 源。
<rssxmlns:msdn="http://msdn.microsoft.com/aboutmsdn/rss/"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:msdndomain="http://msdn.microsoft.com/aboutmsdn/rss/domains"version="2.0"><channel><title>MSDN: Visual Basic</title><link>http://msdn.microsoft.com/vbasic/</link><description>Recently Published Visual Basic Content</description><language>en-us</language><pubDate>Thu, 30 Jun 2005 13:01:02 GMT</pubDate><lastBuildDate>Thu, 30 Jun 2005 13:01:02 GMT</lastBuildDate><generator>MSDN RSS Service 1.1.0.0</generator><ttl>1440</ttl><item><title>June CTP of Visual Studio 2005 Available to MSDN Subscribers</title><description>The latest Community Technical Preview of Visual Studio 2005is now available for download to MSDN subscribers.</description><link>http://msdn.microsoft.com/subscriptions/</link><category domain="msdndomain:ContentType">Announcement</category><category domain="msdndomain:Subject">.NET development</category><msdn:headlineImage>http://msdn.microsoft.comicons/article.gif</msdn:headlineImage><msdn:contentType>Announcement</msdn:contentType><msdn:simpleDate>Jun 27</msdn:simpleDate><guid isPermaLink="false">Titan_1106</guid><pubDate>Tue, 28 Jun 2005 02:00:13 GMT</pubDate></item><!-- more items follow --></channel></rss>
典型的源文件在下載時附帶有相關(guān)信息,但其中部分信息并非所有聯(lián)合提供程序都會包含(例如,MSDN 的標(biāo)題圖像就不是標(biāo)準(zhǔn)信息)。在 XML 結(jié)構(gòu)的頂部是一個 <channel> 節(jié)點,該節(jié)點包含標(biāo)題和說明,用來簡單描述內(nèi)容項的列表。該 <channel> 節(jié)點包含很多子 <item> 節(jié)點,用來表示每篇文章(包括文章的標(biāo)題、說明、發(fā)布日期以及指向全文的鏈接)。
在 Visual Web Developer 2005 Express Edition 中創(chuàng)建新網(wǎng)站之后,我添加了一個“Web 用戶控件”,用來顯示此信息。
ASP.NET 2.0 的功能之一是它既支持 Visual Studio 2003 開發(fā)人員所熟悉的代碼分離模型,也支持(相對比較新的)嵌入代碼模型,后者允許在 .aspx 或 .ascx 文件的 <script> 標(biāo)記內(nèi)編寫所有代碼。盡管使用嵌入代碼的執(zhí)行方式與 ASP.NET 頁的執(zhí)行方式完全相同,我更喜歡代碼分離模型,并且本示例通篇使用代碼分離模型。另外,請您注意,我使用 Visual Basic 來編寫此應(yīng)用程序的代碼。
在設(shè)計器中工作時,我向控件添加了一個 Repeater 控件。該 Repeater 是數(shù)據(jù)綁定控件,用于按照自定義布局顯示數(shù)據(jù)。這是顯示來自 RSS 源的內(nèi)容項列表的最佳方式。如下所示,在設(shè)計時,可以使用與該控件相關(guān)聯(lián)的智能標(biāo)記菜單為該控件設(shè)置數(shù)據(jù)源。但是,對于此應(yīng)用程序,我將在運行時使用 RSS 源來設(shè)置數(shù)據(jù)源。
切換到 .ascx 文件的代碼分離文件 (RSSList.ascx.vb),然后添加 Imports 語句,以便導(dǎo)入包含必要類 [在獲取 RSS 源并將它存儲到本地資源(將綁定到 Repeater)中時必須使用這些類] 的命名空間。
Imports System.NetImports System.Data
除了使用該控件的 Page Load 事件的事件處理程序之外,我還添加了名為 RefreshFeed 的專用幫助器函數(shù)。此函數(shù)獲取 RSS 數(shù)據(jù),并將該數(shù)據(jù)作為 DataSet 返回給 Page Load 事件處理程序。在 RefreshFeed 函數(shù)中,第一行代碼使用 WebRequest 類的共享 Create 函數(shù)創(chuàng)建一個 HttpWebRequest 實例。
Dim rssFeed As HttpWebRequest =DirectCast(WebRequest.Create("http://msdn.microsoft.com/vbasic/rss.xml"), HttpWebRequest)
作為 Create 函數(shù)的輸入?yún)?shù),該代碼將傳遞 RSS 源的目標(biāo) URL。該函數(shù)返回一個 HttpWebRequest 對象,而該對象是一種特殊的 WebRequest 對象,它支持一些額外的屬性和方法,可以通過 HTTP 與服務(wù)器交互。在這種情況下,我的需要對于 HttpWebRequest 來說非常簡單;代碼首先從服務(wù)器獲取響應(yīng) (GetResponse),然后由于響應(yīng)的格式為 XML 格式,因此可以使用接受 Stream 作為輸入?yún)?shù)的 ReadXml 重載方法將響應(yīng)流 (GetResponseStream) 直接加載到 DataSet 中。
Dim rssData As DataSet = New DataSet()rssData.ReadXml(rssFeed.GetResponse().GetResponseStream())
ReadXml 方法會自動推斷 XML 數(shù)據(jù)的架構(gòu)。這意味著源 XML 數(shù)據(jù)的 <channel> 和 <items> 節(jié)點在 DataSet 中被表示為單獨的 DataTable。在 Page Load 事件處理程序中,調(diào)用 RefereshFeed 方法以返回包含 RSS 源數(shù)據(jù)的 DataSet 之后,代碼將以不同的方式訪問通道和項數(shù)據(jù)。DataSet 中的第二個 DataTable 包含通道信息。為了顯示源標(biāo)題和說明,代碼使用 Row 的 ItemArray 屬性從 DataTable 向 Object 數(shù)組中復(fù)制第一行(同時也是僅有的一行)。然后,由于我要確保我找到了正確的數(shù)據(jù)列,代碼分別向 Integer 類型的本地變量指定了標(biāo)題和說明列的順序位置。使用這些值,代碼調(diào)用 Object 數(shù)組的 GetValue 方法,以便將與每一列相關(guān)的值存儲到為該類定義的 Friend 字段中(我將在 Repeater 控件中使用這些值)。
Dim channelItems As Object() = rssData.Tables(1).Rows(0).ItemArrayDim titleColumn As Integer = rssData.Tables(1).Columns("title").OrdinalDim descriptionColumn As Integer = rssData.Tables(1).Columns("description").OrdinalTitle = channelItems.GetValue(titleColumn).ToString()Description = channelItems.GetValue(descriptionColumn).ToString()
接下來,代碼將 Repeater 控件的 DataSource 屬性設(shè)置為 DataSet 中的 DataTable(保留了來自 RSS 源的項內(nèi)容)。最后,代碼調(diào)用 Repeater 的 DatBind 方法將該數(shù)據(jù)源綁定到控件。
Repeater1.DataSource = rssData.Tables(2)Repeater1.DataBind()
在 RssFeed.ascx 控件的源代碼視圖中,我為 Repeater 控件添加了模板,用于顯示該數(shù)據(jù)。在 <HeaderTemplate> 中,代碼以顯示通道標(biāo)題和說明的標(biāo)頭元素作為表的開始。
<HeaderTemplate><table border=0 style="width: 240px; font-size: x-small; color: black; font-family: Verdana;"><thead><tr style="font-weight: bold;"><td><%#Me.Title%></td></tr><tr style="font-style: italic;"><td><%#Me.Description%></td></tr></thead></HeaderTemplate>
同樣,在 <ItemTemplate> 中,代碼顯示了帶有其相關(guān)鏈接的內(nèi)容項的標(biāo)題以及該項的說明。
<ItemTemplate><tr bgcolor="LightBlue" ><td><a target="article" style="text-decoration: none;color: black;" href=<%# DataBinder.Eval(Container.DataItem, "link") %>><%# DataBinder.Eval(Container.DataItem, "title") %> </a></td></tr><tr bgcolor="Ivory"><td style="color: CornFlowerBlue;"><%# DataBinder.Eval(Container.DataItem, "description") %></td></tr></ItemTemplate>
作為最后并且非常必要的一步,我在 .ascx 頁的頂部添加了一條 OutputCache 指令,以便將該控件的輸入緩存一個小時。
<%@ OutputCache Duration="3600" VaryByParam="None" %>
這可以避免在每次用戶訪問包含該控件的頁面時都執(zhí)行一次 RefreshFeed 函數(shù)。如果我不這么做,則當(dāng)有大量用戶訪問我的網(wǎng)站時,會給我的 Web 服務(wù)器和聯(lián)合提供程序之間帶來大量通訊。如果運行該應(yīng)用程序,聯(lián)合的內(nèi)容將如下所示。
在以后的文章中,我將深入探討在 Web 應(yīng)用程序中使用聯(lián)合 RSS 源的可能性。然后,我會鼓勵您下載代碼,并自己試一下。
Peter Bernhardt 是一位獨立軟件開發(fā)人員和架構(gòu)師,居住在舊金山的海灣地區(qū)。他有多年使用 Microsoft 技術(shù)的經(jīng)驗,現(xiàn)在又開始重新關(guān)注 Word Basic??赏ㄟ^將電子郵件發(fā)送至
peter@SharpSense.net 來與 Peter 取得聯(lián)系。