基於ASP.NET AJAX技術開發線上RSS閱讀器

來源:互聯網
上載者:User
文章目錄

內容摘要:本文旨在通過一個簡單的線上RSS閱讀器的開發過程探討基於微軟ASP.NET AJAX架構(特別是用戶端技術)進行新一代ASP.NET 2.0開發所涉及的典型問題。本文章分為兩個部分,上篇介紹本軟體中的資料層與描述層部分。在下篇中,我們轉入整個開發過程的重點—邏輯層的設計。

  【注】本文測試環境:Windows XP專業版+Visual Studio 2005+整套ASP.NET AJAX架構+ASP.NET RSS Toolkit+SQL Server 2005。

  一、RSS技術簡介

  RSS是一種描述和同步網站內容的XML格式,已經成為越來越流行的網站內容訂閱技術。通過這種技術,網站可以極大地提高廣大網站使用者和網站資料之間的資料互動。

  RSS閱讀軟體可以分為案頭離線式和線上式兩大類。有了這種工具,使用者只需要添加初始其所關注的RSS網址,以後系統會自動更新相關內容,網友只需靜待觀察自己感興趣的新聞即可。

  目前存在多種版本的RSS檔案格式,有0.90、0.91、0.92、0.93、0.94、1.0和2.0。其中,最為流行的是2.0版本。下面展示了一個最簡單的2.0版本的RSS檔案的基本格式:

<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Example Channel</title>
<link>http://example.com/</link>
<description>My example channel </description>
<item>
<title>News for September the Second</title>
<link>http://example.com/2002/09/01</link>
<description>other things happened today</description>
</item>
<item>
<title>News for September the First</title>
<link>http://example.com/2002/09/02</link>
</item>
</channel>
</rss>

  由上可以,RSS檔案的主要節點有rss,頻道和item等。其中rss節點表示執行的RSS標準命名空間;頻道節點表示在部落格或新聞群組中的一個類別,通常被譯為頻道;item節點是使用者要查看的主要資訊,其中包括資訊的標題、資訊內容的連結地址及資訊的發布時間等。有關RSS檔案的完整節點介紹,請參考網址http://cyber.lay.harvard.edu/blogs/gems/tech/rss2sample.xml。

  關於Robsman的ASP.NET RSS Toolkit

  很顯然,因RSS檔案版本繁多,而且存在一定差距,如果手動解析XML檔案費時費力。還好,我們可以利用微軟公司開發的開源RSS Toolkit工具包(下載網址:http://blogs.msdn.com/dmitryr/)來簡化之。

  這個工具包具有如下功能:

  1)RSS資料來源控制項—其使用方式與ASP.NET內建的資料來源控制項一樣,它也支援綁定和支援模板化資料繫結,並為其提供顯示所需的資料;

  2)可以在記憶體或磁碟中緩衝遠程RSS提要對應的內容;

  3)基於RSS的URL地址為RSS提要產生易於開發調試的強型別對象;

  4)對程式中產生的RSS提要相應的典型操作進行封裝。

  下面,我們通過一個具體的例子來探討如何使用這個工具包並基於微軟ASP.NET AJAX架構來開發一個簡單的RSS新聞閱讀器。

  二、本系統主要功能及關鍵技術分析

  在正式開工以前,讓我們先來瞭解一下本系統要實現的主要功能以及開發本系統所涉及的主要技術。

  (一)主要功能

  一個線上RSS閱讀器可以把你喜歡的RSS訂閱儲存在伺服器端資料庫中以便後來在方便之時在具有網際網路串連的任何位置進行訪問。典型地,我們可以通過1來大致描述一個RSS閱讀器的工程流程。

  圖1:一個RSS閱讀器的典型工程流程

  根據上面的,我們的RSS閱讀器樣本工程DAjaxRssReader將主要實現以下目標:

  ◆添加RSS頻道

  使用者可以把其新輸入的RSS頻道以及相關的URL資訊儲存到ASP.NET AJAX用戶端資料來源控制項中。並且當然,他們能夠把所有這些資訊儲存到遠端的伺服器SQL Server資料庫中。

  ◆顯示所有RSS頻道

  這主要包括兩種情況:1、當應用程式首先啟動時所有的儲存於伺服器端資料庫中的頻道資訊都應該能夠列出於瀏覽器端;2、當使用者重新整理RSS頻道時,所有的與頻道相關聯的資料都可以從伺服器端讀回並顯示於用戶端。

  ◆顯示選擇的特定RSS頻道的詳細資料

  當使用者選擇某個頻道時,應用程式應該能夠展示出相應的與該頻道相連結的特定網頁內容。

  (二)關鍵技術

  首先,在開發任何典型的Web應用程式的過程中,我們都應儘可能地遵循著名的三層結構原則。的圖2展示了本文中的RSS閱讀器程式相應的三層架構略圖。

  圖2:本文RSS閱讀器程式的整體架構

  接下來,在正式討論所涉及的關鍵技術之前,讓我們快速地瀏覽一下樣本程式首頁面的快照,如下面圖3所示。

  圖3:本文樣本RSS閱讀器程式設計時刻快照

  根據上面所展示的圖形及前面的功能分析,我們大致需要基於以下關鍵技術來開發本文中的應用程式:

  1、在描述層,我們需要使用ASP.NET AJAX用戶端ListView控制項來儲存並顯示所有RSS頻道資訊,還有一個伺服器端UpdatePanel控制項來封裝中的ASP.NET AJAX Control Toolkit控制項Accordion以便最終顯示與你從ListView中點選的項相關聯的網站內容。此外,我們還需要一點CSS技巧來修飾所有相關的控制項。最後,我們還引入了ASP.NET AJAX用戶端校正器(Validator)來實現對使用者輸入的RSS名字和URL的校正功能。

  2、在本文樣本程式中,我們將混合使用JavaScript與xml-script宣告式程式設計方式。一方面,在實際開發環境下,基於ASP.NET AJAX架構的Web應用程式通常是相當複雜的;另一方面,ASP.NET AJAX架構本身也還沒有完全成熟起來以便使我們的構建目標完全基於xml-script宣告式程式設計方式進行開發。儘管實現在實現某些編程時使用JavaScript方式相對xml-script聲明性方式相對更複雜一些(因為ASP.NET AJAX用戶端提供了十分類似於ASP.NET的宣告式程式設計方式),但是,JavaScript方式的好處在於,它能夠控制項開發過程中從伺服器端到用戶端的每一個方面。

  3、對於基於ASP.NET AJAX應用程式的資料層開發而言,線上資料中已經提供了典型的實現模式,本文樣本將秉承這一模式。

  【作者注】在調試本文樣本程式時,我被因引入ASP.NET AJAX Control Toolkit控制項並結合Dmitry Robsman的ASP.NET RSS Toolkit所帶來的用戶端與伺服器端通訊的問題所困擾。根據我的分析,通常情況下,我們無法在一個Web服務內部實現把伺服器端的RssDataSource(RSS.NET Toolkit中的一個類)動態地綁定到Accordion控制項(實際上是一個ASP.NET AJAX服務端擴充器)。因此,為了克服這一難題,我不得不求助於__doPostBack函數來建立用戶端與伺服器端的串連;這明顯會引發一個整面重新整理的問題—這與ASP.NET AJAX規則是根本相衝突的。為此,我不得不引入了ASP.NET AJAX伺服器控制項UpdatePanel來把Accordion控制項“包圍”起來以便實現局部更新效果。當然,使得事情進一步複雜化的另一個因此還在於ASP.NET AJAX用戶端控制項—ListView。從較底層的分析來看,這個ListView控制項還遠遠沒有成熟起來!

  下面,讓我們從資料層設計開發逐步探討整個樣本工程的開發過程。

  三、資料層設計

  (一)資料庫設計

  啟動Visual Studio 2005,選擇“檔案→建立網站…”,然後選擇“ASP.NET AJAX-Enabled Web Site”模板,命名工程為“AjaxRss”,並選擇C#作為內建支援語言,最後點擊OK。注意,此後系統將自動加入對於程式集Microsoft.Web.Preview.dll和System.Web.Extensions.dll的引用。當然,你還會注意到,作為ASP.NET AJAX司令部的伺服器控制項ScriptManager被自動地添加到預設網頁Default.aspx中。

  現在,請右擊工程,選擇“添加新項…”,然後選擇模板“SQL Database”建立一個命名為RssReader.mdf的空資料庫。在本文應用程式中,我們僅在此庫中添加一個表格RssStore(其所有欄位都顯示於下面的表格1中)。此後,我們還要建立四個預存程序:DeleteRecord,GetAllRecords,InsertRecord和UpdateRecord。這四個預存程序分別相應於典型的資料庫CRUD操作(ASP.NET AJAX用戶端資料繫結技術對此提供了較好的支援方案,本文中即展示之)。所有這些內容在此我們不去贅述。

  表格1:表格RssStore相應的結構

  欄位名

類型
說明

Rss_ID
int
表格主鍵

Rss_Name
nchar(32)
RSS頻道名字

Rss_URL
nchar(64)
RSS頻道URI(或者URL)

  (二)Web服務設計

  接下來,我們要編寫一個將從用戶端以AJAX方式進行調用的Web服務。在本文樣本中,我們讓該服務返回一個RssInfo對象(用作資料庫表格RssStore中記錄的OOP封裝器)數組。

  現在,請以滑鼠右擊工程並選擇“添加新項…”建立一個新的Web服務MyDataService.asmx。然後,開啟檔案BookDataService.cs,在其中編寫我們要求的所有的Web方法—DeleteRecord,GetAllRecords,InsertRecord和UpdateRecord。這四個方法與我以前在51CTO上發表的文章中所涉及的基本一致,在此不多贅述。有興趣的讀者也可參考本文相應源碼加以分析。

  下面,我們將進入到使用者介面設計階段。

  四、使用者介面層設計

  根據上面介紹的一般架構,我們可以把整個使用者介面部分劃分成三個子部分:

  1)添加新的RSS頻道資訊;

  2)顯示RSS頻道列表;

  3)顯示指定的RSS頻道內容(即與之相關聯的網站內容)。

  上面給出的圖3已經顯示了本文應用程式的設計時刻的使用者介面。

  在上面的圖3中,位於左上方的是一個ASP.NET AJAX用戶端控制項—ListView;它用於儲存和顯示RSS頻道列表。其下方的.gif動畫(註:它相應於控制項ListView的emptyTemplate模板部分)僅僅是為了產生一種更為友好的使用者體驗效果。動畫頁面的那個較大的矩形區(它包含簡單若干個簡單的ASP.NET AJAX用戶端控制項)域對應一個HTML div標籤(名為“buttonarea”),提供給使用者輸入新的RSS頻道資訊。整個Web頁面的右部是一個ASP.NET AJAX Control Toolkit中的Accordion控制項,它用於顯示指定RSS頻道的詳細資料。有關於頁面中的另外幾個“神秘”的小點與包圍Accordion控制項的ASP.NET AJAX伺服器控制項UpdatePanel及與之相關聯的UpdateProgress控制項,我們將在後面詳細介紹。現在,你肯定注意到了位於頁面最左下角的Rss Toolkit control—RssDataSource控制項,它用於從伺服器端為Accordion控制項提供資料來源(一般來說,我們僅能在運行時刻從伺服器端使用它,因為它是一個伺服器端資料來源控制項。關於這個控制項的細節,後面我們還要介紹)。最後,所有的控制項都被使用一個HTML table元素進行包圍。

  到此為止,我們已經介紹完本軟體中的資料層與描述層部分。在下篇中,讓我們轉入整個開發過程的重點—邏輯層的設計。

五、邏輯層設計

(一)添加RSS頻道

在展開真正的邏輯層設計之前,先讓我們簡單地瀏覽一下下面的草圖4。圖4展示了我對於兩個重要ASP.NET AJAX用戶端控制項—ListView和DataSource以及MS AJAX官方資料中建議的實現用戶端資料繫結架構的理解。

498)this.style.width=498;">

圖4:ASP.NET AJAX架構中建議的典型的用戶端資料繫結架構

從中,我們可以得出如下結論:在實戰環境(本例中也是如此)下,當添加一個新的RSS頻道時,我們並不需要立即把這些資料存放區到伺服器端的SQL Server資料庫中,而是暫時儲存到與用戶端控制項ListView相關聯的資料來源控制項中。因此,你可以已經猜出,該DataSource控制項是支援批更新操作的—支援對於用戶端修改資料的臨時儲存並最終以批處理方式實現補救伺服器端資料庫。上面草圖中的兩個重要方法—“Save”和“Load”在此實現邏輯中起著重要作用。

在這一節中,我們僅需要在用戶端臨時儲存使用者新輸入的RSS頻道資訊。在此,我在操作ListView控制項的過程中遇到了第一個難題。下面先讓我們來看一下相應的源碼。

列表1

<script language="javascript" type="text/javascript">

var g_RSSNameList;

function pageLoad(sender, args) {

g_RSSNameList=$find('RSSNameList');

…………

}

function Add_onclick() {

g_RSSNameList.addItem();

var  index=datatable.get_length()-1;

datatable.getItem(index).setProperty('Rss_ID', index);

datatable.getItem(index).setProperty('Rss_Name', $find('txtRssName').get_text());

datatable.getItem(index).setProperty('Rss_URL', $find('txtRssUrl').get_text());

}

當使用者點擊用戶端HTML Input按鈕“Add the RSS Info”時將調用上面的JavaScript函數Add_onclick(即click事件處理器)。在此,g_RSSNameList是一個全域JavaScript變數,它引用了ListView“RSSNameList”(即負責儲存和顯示與RSS頻道資訊的控制項)。在這個函數中,我們首先調用ListView的addItem方法;此方法能夠把一條空記錄添加在與DataSource控制項關聯的DataTable控制項的最後,同時還能夠使資料集變髒(這一點對於後面我們將討論的“儲存”操作至關重要)。然後,我們得到此空記錄的記錄號。然後,我們調用方法getItem(這個方法與方法getRow完全一致)取回空記錄並調用方法setProperty來填充相應的資料庫表格欄位。注意,在此,我們必須使用用戶端全域方法$find而不是$get;有關其間的差異請參考架構線上資料。最終,我們實現了在用戶端資料來源中插入(即‘添加’)一條記錄。

注意,在此,我使用了最簡單的ASP.NET AJAX用戶端校正器組件—requiredFieldValidator來防止使用者不在文字框內輸入內容。下面是相應的xml-script代碼聲明。

列表2

            

<textBox id="txtRssName">

<validators>

<requiredFieldValidator errorMessage="You must name the RSS!" />

</validators>

</textBox>

<validationErrorLabel id="validator1" associatedControl="txtRssName" />

<textBox id="txtRssUrl">

<validators>

<requiredFieldValidator errorMessage="You must name the Url of the RSS!" />

</validators>

</textBox>

<validationErrorLabel id="validator2" associatedControl="txtRssUrl" />

在此,在第二個文字框架控制項的校正中,你可以選用更好一些的校正器控制項regExValidator(它能夠利用正規運算式對這裡的url進行格式校正)。如果你讓兩個控制項空著(例如僅輸入幾個空白字元),那麼,系統將顯示一個紅色的“*”號—示意你應該輸入一些資料。在調試此程式時,當我保持此兩個文字框為空白(不輸入任何內容),系統看上去毫無反映。這懷疑這是用戶端校正器Validator中存在的一個小小的BUG,有興趣的讀者可作進一步分析。

【作者注】在本文示範程式中,我沒有實現“刪除”和“修改”功能。在此,我強烈建議讀者試著加入這兩個功能。通過這些操作,你的ASP.NET AJAX用戶端編程功力將得到極大提升。

接下來,讓我們探討如何顯示儲存於伺服器端的RSS隧道的問題。

(二)顯示RSS頻道

在這一部分中,要顯示RSS頻道,存在至少兩種情形:

1)當頁面初次載入時,所有儲存於伺服器端SQL Server資料庫中的RSS頻道都將顯示於前面我們提到的用戶端控制項ListView中;
2)當使用者點擊按鈕“Refresh”時,所有原始的儲存於伺服器端SQL Server資料庫中的RSS頻道資訊都被顯示於用戶端控制項ListView中。

現在,首先讓我們來分析第一種情形。下面的列表顯示了相應的xml-script聲明性代碼。

列表3

            

<script type="text/xml-script">

<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">

<components>

<dataSource id="RSSInfoDataSource" serviceURL="MyDataService.asmx" >

</dataSource>

<button id="Save">

<click>

<invokeMethodAction target="RSSInfoDataSource" method="save" />

</click>

<bindings>

<binding dataContext="RSSInfoDataSource" dataPath="isDirtyAndReady"

property="element" propertyKey="disabled" transform="Invert" />

</bindings>

</button>

<button id="Refresh">

<click>

<invokeMethodAction target="RSSInfoDataSource" method="load" />

</click>

<bindings>

<binding dataContext="RSSInfoDataSource" dataPath="isReady" 

property="element" propertyKey="disabled" transform="Invert" />

</bindings>

</button>

<application>

<load>

<invokeMethodAction target="RSSInfoDataSource" method="load"/>

</load>

</application>

</components>

</page>

</script>

在此,我們首先指定DataSource控制項“RSSInfoDataSource”。這個控制項將被ASP.NET AJAX架構以非同步方式綁定到伺服器端DataService“MyDataService”。其次,在最後面的<application>節中,當該Web應用程式啟動時,它相應的load事件方法被調用。然後,在子節<invokeMethodAction>中,資料來源“RSSInfoDataSource”的load方法被調用,這將觸發一次非同步回寄—調用資料服務“MyDataService”的Web方法GetAllRecords。下面的列表展示了這個方法的實現代碼。

列表4

[WebMethod]

[DataObjectMethod(DataObjectMethodType.Select)]

public List<RssInfo> GetAllRecords()

{

return new SqlTaskProvider().GetAllRecords();

}

有關於此方法之前的修改屬性,在此不多贅述,請參考ASP.NET AJAX線上文檔。現在,一旦這個方法執行結束,用戶端ListView控制項“RSSNameList”即被以儲存於服務端SQL Server資料庫表格RssStore中的記錄所填寫。

注意,在此我們略微施了點小技:為了取得較好的使用者體驗感,我們隱藏了兩個欄位Rss_ID和Rss_URL(這兩個欄位中的內容是不需要顯示的)。下面給出的是相應的HTML代碼片斷。

列表5

<div id="searchResults_itemTemplate" >

<span id="searchResults_Rss_ID" style="display: none; visibility: hidden;"></span>

<span id="searchResults_Rss_Name"></span>

<span id="searchResults_Rss_URL" style="display: none; visibility: hidden;"></span>

</div>

不必我們擔心,ASP.NET AJAX架構會自動區分這一情形,並仍然能夠以資料庫記錄資料填充ListView控制項,只不過是隱藏了其中兩個欄位的顯示而已。

現在,讓我們來分析第二種情形—當使用者點擊按鈕“Refresh”時。儘管從字面上看,我們使用的是“Refresh”(即“重新整理”),但是這個按鈕的真正作用是把伺服器端的資料庫資料載入到當前ListView控制項中。這一過程與用戶端的資料控制項DataSource存在著直接的聯絡。下面的xml-script代碼向你展示了相應的編程。

列表6

            
<button id="Refresh">

<click>

<invokeMethodAction target="RSSInfoDataSource" method="load" />

</click>

<bindings>

<binding dataContext="RSSInfoDataSource" dataPath="isReady" 
     property="element" propertyKey="disabled" transform="Invert" />

</bindings>

</button>

從上面的代碼可知,當使用者點擊按鈕“Refresh”時,用戶端DataSource控制項“RSSInfoDataSource”的方法load被調用。然後,Web方法GetAllRecords將被非同步呼叫;最後此Web方法返回的資料被填充到ListView控制項中。

為了完整起見,在本樣本程式中,我們還引入了一個“Save”按鈕,其功能與按鈕“Refresh”恰恰相反。當使用者點擊按鈕“Save”時,所有位於ListView控制項中的最新的RSS頻道資料都將被以AJAX方式(即“非同步”方式)非揮發性儲存體到伺服器端的SQL Server資料庫中。要想進一步探討這個按鈕的作用機制,請參考我發表在51CTO上的另一篇文章“”;在此文章中,我較為全面地分析了ASP.NET AJAX用戶端ListView和ItemList控制項等與以Web服務封裝下的服務端SQL Server資料庫的互動。

(三)顯示指定RSS頻道相應內容

現在,問題變得越來越有趣了。為了顯示一個RSS頻道的內容,為僅需要點擊ListView控制項中一項,然後讓右邊的Accordion控制項展示相應的細節資訊,不就行了?不錯,但這僅是從使用者角度得到的結論。但作為開發人員,為瞭解決這個問題,我花費了大量時間才找到一種實現方案。下面,讓我來逐一向各位介紹。

通過網路取得RSS頻道內容

1、關於ListView控制項

有關ASP.NET AJAX架構提供的“進階”用戶端ListView控制項,我想先簡單地討論幾句。從研究架構相應的源碼檔案PreviewScript.js,我們發現在這個控制項的descriptor塊定義(註:只在位於此塊中的內容才可能在xml-script宣告式程式設計方式中使用)中僅提供了極少數目的屬性,方法與事件定義。下列我們乾脆列出這個控制項的descriptor塊的定義。

列表7

Sys.Preview.UI.Data.ListView.descriptor = {

properties: [ { name: 'alternatingItemCssClass', type: String },

{ name: 'layoutTemplate', type: Sys.Preview.UI.ITemplate },

{ name: 'itemCssClass', type: String },

{ name: 'itemTemplate', type: Sys.Preview.UI.ITemplate },

{ name: 'itemTemplateParentElementId', type: String },

{ name: 'selectedItemCssClass', type: String },

{ name: 'separatorCssClass', type: String },

{ name: 'separatorTemplate', type: Sys.Preview.UI.ITemplate },

{ name: 'emptyTemplate', type: Sys.Preview.UI.ITemplate } ],

events: [ {name: 'renderComplete'} ]

}

在上面的descriptor塊定義中,僅有幾個有限的屬性和一個事件。後面我們將使用的方法,還要求助於控制項的父類DataControl。為此,為能夠控制使用者點擊的ListView控制項中的每一項(對應一條記錄資料),我們不得不進一步研究ListView控制項定義中的prototype塊,並進而求助於JavaScript編程。

2、通過JavaScript編程為ListView添加事件

首先,讓我們列出與上面所有相應的源碼部分。

列表8

            

<script language="javascript" type="text/javascript">

var g_RSSNameList;

function pageLoad(sender, args) {

g_RSSNameList=$find('RSSNameList');

$addHandler($get('RSSNameList'), 'click', clickRowHandler);

}

function clickRowHandler(ev)

{

var s = ev.target;

while (s && (typeof(s.dataIndex) === 'undefined')) {

s = s.parentNode;

}

if (s) {

var idx = s.dataIndex;

//調用與“啞元”控制項dummySrvBtn相應的伺服器端方法

var btn ='<%=dummySrvBtn.ClientID%>';

var txt='<%=txtRssUrl2.ClientID%>';

document.getElementById(txt).value="/s.lastChild.innerText;"

__doPostBack(btn,'');

}

}

……(省略)

function pageUnload() {

//釋放事件處理器

if (clickRowHandler)

$removeHandler($get('RSSNameList'), "click",clickRowHandler);

clickRowHandler=null;

}

在此,我們首先使用全域方法$addHandler來把事件處理器clickRowHandler關聞到ListView控制項RSSNameList的click事件上。接下來,我們來分析這個事件處理器函數的編程。一開始,屬性ev.target指向ListView RSSNameList。當程式執行到if條件陳述式時,變數s指向searchResults_itemTemplate(資料庫記錄正是在其中顯示)。現在,我們可以使用變數idx來取得記錄索引的當前值並且可以擷取我們想取回的任何欄位值(在此,我們僅對最後一個欄位Rss_URL感興趣)。

情況到現在變得越來越複雜了—我們怎樣才能為RssDataSource控制項(注意這是一個第三方伺服器端資料控制項)動態地指定RSS url呢?在此,我的方案是求助於方法“__doPostBack”。根據本文分析,一般情況下,我們無法在一個Web服務方法內實現把RssDataSource動態地綁定到Acccordion控制項。這樣以來,我們只取另尋出路—CodeFile檔案AjaxRssReader.aspx.cs。實驗證明,在這個後台檔案中,我們可以實現上面的目標—把RssDataSource動態地綁定到Acccordion(注意,我們無法在用戶端JavaScript指令碼中實現這一綁定,因為這是一個伺服器端資料來源控制項)。這也正是我們求助於__doPostBack方法的原因,藉助於這個方法,我們可以間接地實現用戶端控制項與伺服器端控制項的通訊。

為了實現上面的目標,現在,我們要建立兩個“啞元”ASP.NET控制項(這僅是我的思路)—一個Button控制項和一個TextBox控制項。由於它們在運行時刻必須是不顯示的,所以我們把它們的尺寸設定為最小值(寬高均為1個像素X),並相應地把其背景設定為淺灰色(這正好相應於按鈕地區“buttonarea”的背景色)。

【作者注】在實驗中,我發現我們無法把兩個“啞元”控制項的Visible屬性設定為false;否則,將出現運行時刻錯誤。

接下來,通過調用方法“__doPostBack”我們間接地調用了伺服器端click事件處理器—dummySrvBtn_Click(object sender,EventArgs e)(此函數位於CodeFile檔案AjaxRssReader.aspx.cs內)。下面是這個函數相應的源碼。

列表9

protected void dummySrvBtn_Click(object sender, EventArgs e)

{

RssDataSource1.Url = txtRssUrl2.Text.Trim();

Accordion1.DataSourceID = "RssDataSource1";

Accordion1.DataBind();

}

現在,我們先略過對這段代碼的分析。

然後,通過把欄位Rss_URL的值賦為相關聯的HTML Input元素txtRssUrl2.ClientID(對應ASP.NET伺服器端Id—txtRssUrl2)的attribute值(對應於對應伺服器端的Text屬性),我們就成功地實現了把資料從用戶端傳輸到伺服器端。

最後,調用方法“__doPostBack”將必然導致一次整個頁面的重新整理—這與AJAX基本思想是根本相違背的。這正是我們引入ASP.NET AJAX伺服器控制項UpdatePanel(它把Accordion控制項相應的地區包圍起來)的原因。注意,在此我們使用UpdatePanel的AsyncPostBackTrigger觸發器來實現使按鈕“dummySrvBtn”的click事件觸發UpdatePanel的重新整理操作。下面是相關的HTML代碼部分。

列表10

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

<Triggers>

<asp:AsyncPostBackTrigger ControlID="dummySrvBtn" EventName="Click" />

</Triggers>

<ContentTemplate>

<ajaxToolkit:Accordion ID="Accordion1" CssClass="myAccordion" HeaderCssClass="header"

…………(省略)

也因此,我們才引入了伺服器控制項UpdateProgress來配合UpdatePanel控制項取得更友好些的使用者體驗。

也許我上面的方案太“醜陋”了;因此,非常希望熱心讀者能夠進一步改進之。

顯示頻道內容

到目前為止,這一步已經變得相當簡單了。事實上,在上面的源碼9中我們已經實現了這一目標。通過對於控制項RssDataSource1的屬性Url的動態賦值,然後把它綁定到控制項Accordion1,進而調用Accordion1的方法DataBind,我們最終實現根據使用者點擊的頻道標題資訊顯示該頻道的具體網頁內容。

【作者注】第一,通過Google搜尋網際網路,我竟然沒有發現實現RssDataSource控制項動態賦值的相關樣本。第二,由於某些RSS內容中可能不包含author欄位,所以我乾脆在控制項Accordion的<ContentTemplate>塊中注釋掉此欄位。

最後,讓我們來看一下我們的最終成果吧,如5所示。

498)this.style.width=498;">

圖5:在使用者點擊RSS頻道“Scott Guthrie”後的樣本程式運行時刻快照

六、總結

在本文中我們使用微軟ASP.NET AJAX架構開發了一個簡單的RSS閱讀器程式。作為一個示範程式,我們僅為了探討這個架構的基本使用思路;所以,此軟體還存在許多地方有待改進:

1)僅使用ASP.NET AJAX用戶端技術開發
2)進一步探討實現用戶端與伺服器通訊的其它方式
3)使用用戶端控制項XSLTView控制項來取代本文所使用的ASP.NET AJAX Control Toolkit控制項Accordion來顯示RSS頻道內容
4)使用用戶端控制項Validator—regExValidator來更為嚴格地校正使用者輸入的RSS頻道地址
5)進一步支援使用者在運行時刻實現對RSS頻道資訊的刪除/修改
6)增加另外的類型RSS並且為使用者提供分類管理
………

有興趣的朋友可以根據上面這些提示進一步改進本文樣本。
原文地址:http://developer.51cto.com/art/200708/53158_3.htm

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.