Coding4Fun: 一個(gè)簡(jiǎn)單的 RSS 源發(fā)布日期: 10/27/2005 | 更新日期: 10/27/2005
Peter Bernhardt 很多年以前,我得到一個(gè)經(jīng)驗(yàn):我不需要了解所有事情就能了解整個(gè)世界。當(dāng)然,得出這個(gè)結(jié)論本身就是一種自大的行為。但是這種自大源于年輕無知,現(xiàn)在我更清楚地認(rèn)識(shí)到了這一點(diǎn)。實(shí)際上,這個(gè)事實(shí)只有在 Internet 時(shí)代才被放大了,因?yàn)槲野l(fā)現(xiàn)我不可能跟上 Web 上永不停止的信息、思想和觀念流。甚至在我感興趣的領(lǐng)域,我也很難跟上 Visual Basic、Visual C# 和 .NET Framework 的最新發(fā)展。 因此,在接下來的幾個(gè)課程中,我將探索通過不同的方法來使用您很可能已經(jīng)熟悉的工具:RSS(即真正簡(jiǎn)單的聯(lián)合發(fā)布系統(tǒng))- 一種能夠大大減輕信息超載現(xiàn)象的技術(shù)。 作為快速入門,Wikpedia 將 RSS 描述為:“對(duì) Web 內(nèi)容的間斷介紹以及指向完整內(nèi)容的鏈接。此信息以 XML 文件的形式提供,稱為 RSS 源、webfeed、RSS 流或 RSS 通道。除了使聯(lián)合更方便以外,RSS 還使經(jīng)常訪問網(wǎng)站的讀者能夠使用新信息聯(lián)合器跟蹤該網(wǎng)站的更新。” [有關(guān)完整的信息,請(qǐng)參閱 RSS on Wikpedia(英文)。] 在開始以前,讓我們先來看一個(gè)可以使用 Visual Web Developer 2005 Express Edition 創(chuàng)建的簡(jiǎn)單 RSS 源閱讀器。我將創(chuàng)建一個(gè)控件,從所需的站點(diǎn)中提取 RSS 源,并對(duì)該內(nèi)容進(jìn)行組織以顯示在網(wǎng)頁(yè)上。當(dāng)然,如果您是為了自己使用而聯(lián)合內(nèi)容,也可以創(chuàng)建 Windows 應(yīng)用程序形式的 RSS 源閱讀器,或者利用任何一個(gè)已有的免費(fèi) RSS 客戶端應(yīng)用程序 [例如,RSS Reader(英文)或 SharpReader(英文)]。但是,在 Web 應(yīng)用程序中聯(lián)合內(nèi)容有其他目的 - 它使您能夠擴(kuò)展自己創(chuàng)建的內(nèi)容,并豐富了訪問您站點(diǎn)的用戶的體驗(yàn)。 在涉及代碼之前,讓我們先看一小段典型的 RSS 2.0 文件內(nèi)容。在此示例中,聯(lián)合的提供程序?yàn)?Microsoft 的 MSDN 網(wǎng)站,并且我使用了 Visual Basic 內(nèi)容專用的 RSS 源。 <rss xmlns:msdn="http://msdn.microsoft.com/aboutmsdn/rss/" xmlns:dc="http:///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 2005 is 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> 典型的源文件在下載時(shí)附帶有相關(guān)信息,但其中部分信息并非所有聯(lián)合提供程序都會(huì)包含(例如,MSDN 的標(biāo)題圖像就不是標(biāo)準(zhǔn)信息)。在 XML 結(jié)構(gòu)的頂部是一個(gè) <channel> 節(jié)點(diǎn),該節(jié)點(diǎn)包含標(biāo)題和說明,用來簡(jiǎn)單描述內(nèi)容項(xiàng)的列表。該 <channel> 節(jié)點(diǎn)包含很多子 <item> 節(jié)點(diǎn),用來表示每篇文章(包括文章的標(biāo)題、說明、發(fā)布日期以及指向全文的鏈接)。 在 Visual Web Developer 2005 Express Edition 中創(chuàng)建新網(wǎng)站之后,我添加了一個(gè)“Web 用戶控件”,用來顯示此信息。 ![]() ASP.NET 2.0 的功能之一是它既支持 Visual Studio 2003 開發(fā)人員所熟悉的代碼分離模型,也支持(相對(duì)比較新的)嵌入代碼模型,后者允許在 .aspx 或 .ascx 文件的 <script> 標(biāo)記內(nèi)編寫所有代碼。盡管使用嵌入代碼的執(zhí)行方式與 ASP.NET 頁(yè)的執(zhí)行方式完全相同,我更喜歡代碼分離模型,并且本示例通篇使用代碼分離模型。另外,請(qǐng)您注意,我使用 Visual Basic 來編寫此應(yīng)用程序的代碼。 在設(shè)計(jì)器中工作時(shí),我向控件添加了一個(gè) Repeater 控件。該 Repeater 是數(shù)據(jù)綁定控件,用于按照自定義布局顯示數(shù)據(jù)。這是顯示來自 RSS 源的內(nèi)容項(xiàng)列表的最佳方式。如下所示,在設(shè)計(jì)時(shí),可以使用與該控件相關(guān)聯(lián)的智能標(biāo)記菜單為該控件設(shè)置數(shù)據(jù)源。但是,對(duì)于此應(yīng)用程序,我將在運(yùn)行時(shí)使用 RSS 源來設(shè)置數(shù)據(jù)源。 ![]() 切換到 .ascx 文件的代碼分離文件 (RSSList.ascx.vb),然后添加 Imports 語(yǔ)句,以便導(dǎo)入包含必要類 [在獲取 RSS 源并將它存儲(chǔ)到本地資源(將綁定到 Repeater)中時(shí)必須使用這些類] 的命名空間。 Imports System.Net Imports System.Data 除了使用該控件的 Page Load 事件的事件處理程序之外,我還添加了名為 RefreshFeed 的專用幫助器函數(shù)。此函數(shù)獲取 RSS 數(shù)據(jù),并將該數(shù)據(jù)作為 DataSet 返回給 Page Load 事件處理程序。在 RefreshFeed 函數(shù)中,第一行代碼使用 WebRequest 類的共享 Create 函數(shù)創(chuàng)建一個(gè) HttpWebRequest 實(shí)例。 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ù)返回一個(gè) HttpWebRequest 對(duì)象,而該對(duì)象是一種特殊的 WebRequest 對(duì)象,它支持一些額外的屬性和方法,可以通過 HTTP 與服務(wù)器交互。在這種情況下,我的需要對(duì)于 HttpWebRequest 來說非常簡(jiǎn)單;代碼首先從服務(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 方法會(huì)自動(dòng)推斷 XML 數(shù)據(jù)的架構(gòu)。這意味著源 XML 數(shù)據(jù)的 <channel> 和 <items> 節(jié)點(diǎn)在 DataSet 中被表示為單獨(dú)的 DataTable。在 Page Load 事件處理程序中,調(diào)用 RefereshFeed 方法以返回包含 RSS 源數(shù)據(jù)的 DataSet 之后,代碼將以不同的方式訪問通道和項(xiàng)數(shù)據(jù)。DataSet 中的第二個(gè) DataTable 包含通道信息。為了顯示源標(biāo)題和說明,代碼使用 Row 的 ItemArray 屬性從 DataTable 向 Object 數(shù)組中復(fù)制第一行(同時(shí)也是僅有的一行)。然后,由于我要確保我找到了正確的數(shù)據(jù)列,代碼分別向 Integer 類型的本地變量指定了標(biāo)題和說明列的順序位置。使用這些值,代碼調(diào)用 Object 數(shù)組的 GetValue 方法,以便將與每一列相關(guān)的值存儲(chǔ)到為該類定義的 Friend 字段中(我將在 Repeater 控件中使用這些值)。 Dim channelItems As Object() = rssData.Tables(1).Rows(0).ItemArray Dim titleColumn As Integer = rssData.Tables(1).Columns("title").Ordinal Dim descriptionColumn As Integer = rssData.Tables(1).Columns("description").Ordinal Title = channelItems.GetValue(titleColumn).ToString() Description = channelItems.GetValue(descriptionColumn).ToString() 接下來,代碼將 Repeater 控件的 DataSource 屬性設(shè)置為 DataSet 中的 DataTable(保留了來自 RSS 源的項(xiàng)內(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)容項(xiàng)的標(biāo)題以及該項(xiàng)的說明。 <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 頁(yè)的頂部添加了一條 OutputCache 指令,以便將該控件的輸入緩存一個(gè)小時(shí)。 <%@ OutputCache Duration="3600" VaryByParam="None" %> 這可以避免在每次用戶訪問包含該控件的頁(yè)面時(shí)都執(zhí)行一次 RefreshFeed 函數(shù)。如果我不這么做,則當(dāng)有大量用戶訪問我的網(wǎng)站時(shí),會(huì)給我的 Web 服務(wù)器和聯(lián)合提供程序之間帶來大量通訊。如果運(yùn)行該應(yīng)用程序,聯(lián)合的內(nèi)容將如下所示。 ![]() 在以后的文章中,我將深入探討在 Web 應(yīng)用程序中使用聯(lián)合 RSS 源的可能性。然后,我會(huì)鼓勵(lì)您下載代碼,并自己試一下。 Peter Bernhardt 是一位獨(dú)立軟件開發(fā)人員和架構(gòu)師,居住在舊金山的海灣地區(qū)。他有多年使用 Microsoft 技術(shù)的經(jīng)驗(yàn),現(xiàn)在又開始重新關(guān)注 Word Basic??赏ㄟ^將電子郵件發(fā)送至 peter@SharpSense.net 來與 Peter 取得聯(lián)系。 |
|