CH07 P126 - Gotop

29
7-35 7-8 如何使用控制項參數 從之前的範例可以瞭解, SqlDataSource 控制項用來從 SQL Server 資料庫提 取資料的 SELECT 陳述式或預存程序都可以內含參數,此舉最大的好處, 就是我們可以動態篩選出所需的資料列,而不是一股腦兒將所有的資料都下 載至用戶端。事實上不僅僅是提取資料,新增、修改、刪除、排序以及分頁 資料的操作,全都可以搭配參數來使用。 不論您是要搭配參數來完成何種操作,最重要的議題,就是如何將條件值指 派給參數。參數的條件值可能來自使用者於某控制項中的操作,來自另外一 個網頁的查詢字串,來自 Cookie… 等等。比方說,以先前的網頁範例 CH7_DemoForm004.aspxCH7_DemoForm005.aspx 以及 CH7_DemoForm006. aspx 而言,參數的條件值就是由使用者在下拉式清單方塊中所選取的選項來 提供。 ASP.NET 3.5 最貼心的地方,就是透過一個簡易的介面來讓您選取參數之條 件值的來源,您甚至還可以設定參數的名稱、型別、預設值等等。如果參 數的條件值是來自網頁上某一個控制項的屬性值,請於 「設定資料來源」 「定義參數」頁面中,依下列步驟進行設定: 1. 「參數來源」 下拉式清單方塊中選取 Control 選項(此舉表示建立一 ControlParameter 物件)。 2. Control ID 下拉式清單方塊中選取要提供條件值的控制項。一旦您 選取了某一個控制項,ASP.NET 會自動以您所選取之控制項的預設屬 性值作為參數的條件值,舉例來說,如果您選取了一個 DropDownList 控制項,則會以其 SelectedValue 屬性值作為參數的條件值(如圖表 7-32 所示)。當然,不同控制項的預設屬性亦有所不同,圖表 7-33 列出各 種控制項的預設屬性。如果您想要採用預設屬性以外的屬性值來做為參 數的條件值,可以在稍後的步驟中變更。

Transcript of CH07 P126 - Gotop

Page 1: CH07 P126 - Gotop

7-35

7-8 如何使用控制項參數

從之前的範例可以瞭解,SqlDataSource 控制項用來從 SQL Server 資料庫提

取資料的 SELECT 陳述式或預存程序都可以內含參數,此舉最大的好處,

就是我們可以動態篩選出所需的資料列,而不是一股腦兒將所有的資料都下

載至用戶端。事實上不僅僅是提取資料,新增、修改、刪除、排序以及分頁

資料的操作,全都可以搭配參數來使用。

不論您是要搭配參數來完成何種操作,最重要的議題,就是如何將條件值指

派給參數。參數的條件值可能來自使用者於某控制項中的操作,來自另外一

個網頁的查詢字串,來自 Cookie…等等。比方說,以先前的網頁範例

CH7_DemoForm004.aspx、CH7_DemoForm005.aspx 以及 CH7_DemoForm006.

aspx 而言,參數的條件值就是由使用者在下拉式清單方塊中所選取的選項來

提供。

ASP.NET 3.5 最貼心的地方,就是透過一個簡易的介面來讓您選取參數之條

件值的來源,您甚至還可以設定參數的名稱、型別、預設值…等等。如果參

數的條件值是來自網頁上某一個控制項的屬性值,請於「設定資料來源」的

「定義參數」頁面中,依下列步驟進行設定:

1. 從「參數來源」下拉式清單方塊中選取 Control 選項(此舉表示建立一

個 ControlParameter 物件)。

2. 從 Control ID 下拉式清單方塊中選取要提供條件值的控制項。一旦您

選取了某一個控制項,ASP.NET 會自動以您所選取之控制項的預設屬

性值作為參數的條件值,舉例來說,如果您選取了一個 DropDownList

控制項,則會以其 SelectedValue 屬性值作為參數的條件值(如圖表 7-32

所示)。當然,不同控制項的預設屬性亦有所不同,圖表 7-33 列出各

種控制項的預設屬性。如果您想要採用預設屬性以外的屬性值來做為參

數的條件值,可以在稍後的步驟中變更。

Page 2: CH07 P126 - Gotop

7-36

圖表 7-32

提供條件值給參數的控制項 預設屬性

Label,TextBox Text CheckBox,RadioButton Checked ListBox,DropDownList,CheckBoxList,RadioButtonList

SelectedValue

GridView , DetailsView , FormView ,

DataList SelectedValue(構成主索引鍵的第一個欄位,也就

是 DataKeyNames 屬性中的第一個欄位)

TreeView,Menu SelectedValue

Calendar SelectedDate

FileUpload FileBytes

圖表 7-33

3. 如果您想要替參數指定預設值,請於 DefaultValue 文字方塊中輸入預

設值。是否要輸入預設值完全由您視需要自行決定,也就是說,這是非

必要的設定。

請記得在參數名稱前加上參數前置詞 @

Page 3: CH07 P126 - Gotop

7-37

什麼時候會使用預設值呢?當參數來源值被評量為 null 時,就會使用預

設值。

圖表 7-34

請拖曳視窗的右下角以便擁有更完整的畫面空間來設定參數的屬性

Page 4: CH07 P126 - Gotop

7-38

4. 對於一般單純的應用而言,至此即可完成參數的設定作業。但是如果您

想對參數做更完整的設定,請如圖表 7-34 所示,按一下「顯示進階屬

性」超連結,然後依序進行下列定義:

ConvertEmptyStringToNull - 此屬性的預設值為 True,表示如果

控制項提供給參數的條件值是 String.Empty(也就是空字串),則

會將其轉換成 Null(也就是 Nothing),既然轉換成 Null,當然也

就 會 使 用 預 設 值 ; 如 果 您 不 希 望 這 樣 處 理 , 亦 即 維 持

String.Empty,請將此屬性設定成 False。

Direction - 請大家注意,只想當 SqlDataSource 控制項使用 SQL

Server 資料庫中的預存程序來提取資料時,才需要設定此屬性。說

明如下:

● 輸入參數(Input Parameter)

您可以將資料值傳遞給預存程序,而預存程序用來接收傳遞進來

之資料值的參數就是所謂的「輸入參數」(Input Parameters)。

預存程序可以宣告一或多個輸入參數,而輸入參數的主要用途,

就是用來篩選資料。因此當我們替 SqlDataSource 控制項定義參

數時,如果該參數就是純粹用來篩選資料,則應該將此參數的

Direction 屬性設定成 Input(此亦為預設值)。

● 輸出參數(Output Parameter)

您除了能夠將資料傳遞給預存程序之外,預存程序亦能夠將資料

傳回給呼叫它的前端程式,重點在於,預存程序是透過輸出參數

來傳回資料。也就是說,當 SqlDataSource 控制項所使用的預存

程序擁有一或多個輸出參數時,您必須替 SqlDataSource 控制項

定義相同數目的一或多個參數,並且將這些參數的 Direction 屬

性設定成 Output 或 InputOutput,以便使用這些參數來接受預

存程序透過輸出參數傳回給它的資料。

● 傳回值

SQL Server 的預存程序可以使用 RETURN 陳述式將一個整數傳

回給呼叫者程式。如果您並未於 RETURN 陳述式中指定要傳回

Page 5: CH07 P126 - Gotop

7-39

任何值,預設將會傳回數值 0。此外,於預存程序中,RETURN

陳述式不能傳回 NULL值,如果預存程序嚐試要傳回 NULL 值,

將會出現錯誤訊息並且傳回 0。

當 SqlDataSource 控制項所採用的預存程序使用了 RETURN 陳

述式傳回一個整數值,則您必須替 SqlDataSource 控制項定義一

個參數,並且將此參數的 Direction 屬性設定成 ReturnValue,

以便使用該參數來接受預存程序所傳回的整數值。

PropertyName - 之前就曾經提到過,當我們從 Control ID 下拉

式清單方塊中選取要提供條件值的控制項,ASP.NET 會自動以您所

選取之控制項的預設屬性值作為參數的條件值(如圖表 7-33 所

示)。如果您不希望以控制項的預設屬性的值做為參數的條件值,

而 希 望 以 控 制 項 的 其 他 屬 性 做 為 參 數 的 條 件 值 , 請 從

PropertyName 屬性的下拉式清單方塊中選取其他屬性。

在此提醒大家,PropertyName 屬性的設定值可以是一個使用 Eval

語法來識別複雜控制項屬性的運算式。

● Size - 此屬性用來設定參數的大小。

● Type - 此屬性用來設定參數的型別。

範例 1 使用控制項參數製作快速輸入搜尋介面

圖表 7-35 是網頁範例 CH7_DemoForm007.aspx 的執行畫面,您只需要輸入

部門名稱並按下 Enter 鍵,就會搜尋出該部門的資料並顯示在 ListView 控制

項中。設計技巧說明如下:

Page 6: CH07 P126 - Gotop

7-40

圖表 7-35

這是一個 ListView控制項

Page 7: CH07 P126 - Gotop

7-41

如圖表 7-36 所示,我們使用 SqlDataSource 控制項做為 ListView 控制

項的資料來源。

圖表 7-36

從圖表 7-35 的操作過程可以瞭解,做為 ListView 控制項之資料來源的

SqlDataSource 控制項是使用輸入部門名稱之 TextBox 控制項的 Text

屬性值來篩選資料,欲達此目的,您必須如圖表 7-37 所示進行設定。

Page 8: CH07 P126 - Gotop

7-42

圖表 7-37

再次提醒大家,在 TextBox 控制項中輸入資料之後按下 Enter 鍵要能夠

立即回傳,必須將 TextBox 控制項的 AutoPostBack 屬性設定成 True。

圖表 7-38

Page 9: CH07 P126 - Gotop

7-43

範例 2 示範使用 GridView 控制項做為參數的控制項來源-重要!!

圖表 7-38 是網頁範例 CH7_DemoForm008.aspx 的執行畫面,當您從第一個

GridView 控制項中選取某一筆客戶訂單資料列時,訂單明細會顯示在下方

的 ListView 控制項中。很顯然,本範例是以 GridView 控制項來提供條件值

給做為 ListView 控制項之 SqlDataSource 控制項中的參數(如圖表 7-39 所

示)。

圖表 7-39

本網頁範例看似單純,但是其中卻蘊含了一些技術概念與技巧。大家必須瞭

解,GridView 控制項是使用 DataKeyNames 屬性來定義資料來源的主索引

鍵,以便唯一識別資料來源的每一筆資料列。重點是,主索引鍵可以是單一

欄位或多個欄位組合而成。如果主索引鍵是多個欄位組合而成,則當使用者

於 GridView 控制項中選取某一筆資料列時, GridView 控制項的

SelectedValue 屬性將只會傳回 DataKeyNames 屬性所指定之主索引鍵的第

一個欄位。

Page 10: CH07 P126 - Gotop

7-44

以本網頁範例而言,當使用者從 GridView 控制項中選取某一筆客戶訂單資

料時,必須將「訂單編號」傳遞給 ListView 控制項之 SqlDataSource 控制

項的參數,才能取得正確的訂貨明細。GridView 控制項的主索引鍵是由「客

戶編號」與「訂單號碼」組合而成,如果按照正常操作程序來設定 GridView

控制項之資料來源的 SELECT 陳述式的話,DataKeyNames 屬性的設定值

將如下所示,也就是「客戶編號」會擺在前面,而「訂單號碼」則會擺在後

面:

<asp:GridView ID="GridView1" runat="server"

DataKeyNames="客戶編號, 訂單號碼" ...>

...

...

</asp:GridView>

顯然此舉將造成使用者於 GridView 控制項中選取某一筆客戶訂單資料列

時,會將「客戶編號」傳遞給 ListView 控制項之 SqlDataSource 控制項的

參數,而造成錯誤。為了能夠傳遞「訂單號碼」給 ListView 控制項之

SqlDataSource 控制項的參數,我們必須如圖表 7-40 所示,自行手動調整

GridView 控制項之 DataKeyNames 屬性的設定值,使得「訂單號碼」成為

主索引鍵的第一個欄位,而「客戶編號」成為主索引鍵的第二個欄位。

圖表 7-40

Page 11: CH07 P126 - Gotop

7-45

圖表 7-41

範例 3 示範使用兩個控制項提供條件值給參數

圖表 7-41 是網頁範例 CH7_DemoForm009.aspx 的執行畫面,您可以快速檢

視某一位客戶在某一年當中,每一個月份的訂貨金額。本範例所要凸顯的重

點,就是您可以使用多個控制項提供條件值給 SqlDataSource 控制項的參

數。以本範例而言,做為 GridView 控制項之 SqlDataSource 控制項的

Page 12: CH07 P126 - Gotop

7-46

CustomerID 與 Year 參 數 的 條 件 值 , 分 別 是 由 DropDownList 與

RadioButtonList 控制項的 SelectedValue 屬性值所提供(如圖表 7-42 所示)。

圖表 7-42

範例 4 示範 SqlDataSource控制項如何搭配使用 SQL Server預存程

序之輸入參數、輸出參數與傳回值 - 重要!!

圖表 7-43 是網頁範例 CH7_DemoForm010.aspx 的執行畫面,其特色在於,

GridView 控制項的 SqlDataSource 控制項是透過預存程序來提取資料,更重

要的是,我們會在網頁中取得預存程序透過輸出參數與 RETURN 陳述式所

傳回的資料值。

Page 13: CH07 P126 - Gotop

7-47

圖表 7-43

我們所使用的預存程序是「北風貿易」資料庫中的 sp_SalaryByDepartment,

其程式碼如下所列:

CREATE PROCEDURE [dbo].[sp_SalaryByDepartment]

@department nvarchar(10), 輸入參數

@average money OUTPUT, 輸出參數

@maximum money OUTPUT, 輸出參數

@minimum money OUTPUT 輸出參數

AS

SELECT @average = AVG(目前薪資),

@maximum = MAX(目前薪資),

@minimum = MIN(目前薪資)

FROM 章立民研究室

WHERE 部門= @department;

SELECT 員工編號,姓名,性別,地址, 目前薪資, 部門

FROM 章立民研究室 WHERE 部門= @department;

此 GridView控制項的 SqlDataSource控制項透過預存程序來提取資料

在網頁中取得預存程序透過輸出參數與 RETRUN陳述式所傳回的資料值

Page 14: CH07 P126 - Gotop

7-48

-- 傳回最近一道陳述式所影響的資料列數。

RETURN @@ROWCOUNT; 使用 RETURN 陳述式傳回一個整數

從以上的程式碼可以看出,預存程序 sp_SalaryByDepartment 定義了一個

名稱為 @department 的輸入參數,當 SqlDataSource 控制項呼叫此預存程

序時,會將使用者從下拉式清單方塊中所選擇的部門傳遞給它,以便能夠順

利篩選出特定部門的資料列。預存程序 sp_SalaryByDepartment 還定義了

三個輸出參數:@average、@maximum 與 @minimum,它們分別用來持

有每一個部門的平均薪資、最高薪資與最低薪資,藉由輸出參數,便能將這

三項統計資訊傳回給呼叫它的前端程式。預存程序 sp_SalaryByDepartment最後使用 RETURN 陳述式傳回最近一道陳述式所影響的資料列數目,以其

所在的位置而言,剛好就會傳回特定部門的人數。為了能夠順利傳遞參數給

預存程序,並且接收預存程序透過輸出參數與 RETURN 陳述式傳回給前端

程式的資料值,您必須如下所示,定義 SqlDataSource 控制項的各個參數:

<asp:SqlDataSource ID="SqlDataSource2" runat="server"

ConnectionString="<%$ ConnectionStrings:chtNorthwind %>"

SelectCommand="sp_SalaryByDepartment" SelectCommandType="StoredProcedure">

<SelectParameters>

<asp:ControlParameter ControlID="DropDownList_Department" Name="department"

PropertyName="SelectedValue" Type="String" />

<asp:Parameter Direction="Output" Name="average" Type="Decimal" />

<asp:Parameter Direction="Output" Name="maximum" Type="Decimal" />

<asp:Parameter Direction="Output" Name="minimum" Type="Decimal" />

<asp:parameter Direction="ReturnValue" Name="ret" Type="Int32" />

</SelectParameters>

</asp:SqlDataSource>

本網頁範例的另外一項技巧,就是如何去取得 SqlDataSource 控制項之各個

輸出參數與傳回值參數的資料值。由於當資料提取操作完成後,就會引發

SqlDataSource 控 制 項 的 Selected 事 件 , 並 且 會 傳 遞 進 來

SqlDataSourceStatusEventArgs 型 別 的 引 數 物 件 , 透 過

SqlDataSourceStatusEventArgs 物件就可以取得用於執行資料操作的

DbCommand 物件,並進而取得 SqlDataSource 控制項之各個輸出參數與傳

回值參數的資料值。以本網頁範例而言,我們必須替 SqlDataSource 控制項

的 Selected 事件處理常式撰寫下列程式碼:

Page 15: CH07 P126 - Gotop

7-49

protected void SqlDataSource2_Selected(object sender, SqlDataSourceStatusEventArgs e)

{

IDbCommand cmd = e.Command;

SqlParameter Return_Param;

SqlParameter Average_Param;

SqlParameter Maximum_Param;

SqlParameter Minimum_Param;

Return_Param = (SqlParameter)cmd.Parameters["@ret"];

Average_Param = (SqlParameter)cmd.Parameters["@average"];

Maximum_Param = (SqlParameter)cmd.Parameters["@maximum"];

Minimum_Param = (SqlParameter)cmd.Parameters["@minimum"];

this.TextBox1.Text = "傳回值參數名稱:" +

Return_Param.ParameterName + ",參數值(人數):" +

Return_Param.Value.ToString();

this.TextBox2.Text = "輸出參數名稱:" +

Average_Param.ParameterName + ",參數值(平均薪資):" +

Average_Param.Value.ToString();

this.TextBox3.Text = "輸出參數名稱:" +

Maximum_Param.ParameterName + ",參數值(最高薪資):" +

Maximum_Param.Value.ToString();

this.TextBox4.Text = "輸出參數名稱:" +

Minimum_Param.ParameterName + ",參數值(最低薪資):" +

Minimum_Param.Value.ToString();

}

當透過 SqlDataSource 控制項完成資料的提取、新增、修改與刪除之後,就會引發其 Selected、Inserted、Updated與 Deleted事件,並且傳遞進來一個 SqlDataSourceStatusEventArgs型別的引數物件。我們可以在這些事件的事件處理常式中,透過 SqlDataSourceStatusEventArgs物件去取得資料庫操作的相關資訊。比方說,您可以使用它的 AffectedRows屬性來取得被資料庫操作所影響的資料列數目,使用 Command 屬性來取得用於執行資料庫操作的 DbCommand物件,並且使用 Exception屬性來取得資料操作期間的任何例外狀況。由此可知,藉由在 Selected、Inserted、Updated 與Deleted事件處理常式中撰寫程式碼,我們可以驗證資料並執行額外的處理。

事實上,SqlDataSource控制項提供了許多事件來讓您在資料操作期間去處理來源資料物件。圖表 7-44列出這些事件、相關的事件引數以及事件處理常式類別。

Page 16: CH07 P126 - Gotop

7-50

說明

事件引數 事件

事件處理常式

Selecting 事件會在資料被提取之前引發。

SqlDataSourceSelectingEventArgs Selecting

SqlDataSourceSelectingEventHandler 在執行新增、修改與刪除操作之前引發。

SqlDataSourceCommandEventArgs Inserting Updating Deleting SqlDataSourceCommandEventHandler

在資料的提取、新增、修改與刪除操作完成之後引發。

SqlDataSourceStatusEventArgs

Selected Inserted Updated Deleted

SqlDataSourceStatusEventHandler

圖表 7-44

7-9 如何使用表單參數

除了使用控制項的屬性值來提供條件值給 SqlDataSource 控制項的參數之

外,您還可以使用 HTML 表單欄位的值來提供條件值。欲達此目的,請如

圖表 7-45 所示,從「參數來源」下拉式清單方塊中選取 Form 選項(此舉

表示建立一個 FormParameter 物件),然後於 FormField 文字方塊中鍵入

提供條件值之表單欄位的名稱(此舉表示設定 FormParameter 物件的

FormField 屬性),並視需要進行其他各項設定。

Page 17: CH07 P126 - Gotop

7-51

圖表 7-45

範例 示範如何結合表單參數與 GridView 控制項製作一個新增、修

改與刪除資料介面

正如大家所知道的,GridView 控制項並不提供新增資料的介面功能,不過

大家不用灰心,因為只要結合表單參數,就可以實作出一個具備新增、修改

與刪除資料介面,網頁範例 CH7_DemoForm011.aspx 即是此一想法的具體

實踐。如圖表 7-46 所示,使用者在各個控制項中輸入資料之後按下「新增

資料」按鈕,所新增的資料會立即顯示在 GridView 控制項中。

請於此輸入提供條件值之表單欄位的名稱

Page 18: CH07 P126 - Gotop

7-52

圖表 7-46

要能夠完成資料的新增、修改與刪除作業,當然必須分別替 SqlDataSource

控制項(它做為 GridView 控制項的資料來源)的 DeleteCommand、

UpdateCommand 與 InsertCommand 屬性定義 DELETE、UPDATE 與

INSERT 陳述式,就本範例的訴求而言,還必須將 INSERT 陳述式中的各

個參數定義為表單參數,並且以特定的表單欄位來提供資料值給表單參數。

Page 19: CH07 P126 - Gotop

7-53

比方說,以下面這一段標記而言,表單參數“作者代號”的值將來自 ID 屬

性值為 txtAuthorID 的表單欄位(這是一個 TextBox 控制項):

<InsertParameters>

<asp:FormParameter Name="作者代號" FormField="txtAuthorID" Type="String" />

...

</InsertParameters>

以下我們列出 SqlDataSource 控制項在完整標記內容,以便讓大家一窺其全

貌:

<asp:SqlDataSource ID="SqlDataSource2" runat="server"

ConnectionString="<%$ ConnectionStrings:chtNorthwind %>"

DeleteCommand="DELETE FROM [作者] WHERE [作者代號] = @作者代號"

UpdateCommand="UPDATE 作者 SET 作者姓名=@作者姓名,性別=@性別,聯絡電話=@聯絡電話,

聯絡地址=@聯絡地址,簽約否=@簽約否,版稅=@版稅 WHERE 作者代號 = @作者代號"

InsertCommand="INSERT INTO 作者

(作者代號, 作者姓名,性別,血型,聯絡電話,聯絡地址,郵遞區號,簽約否,版稅)

VALUES

(@作者代號, @作者姓名,@性別,@血型,@聯絡電話,@聯絡地址,@郵遞區號, @簽約否, @版稅)"

SelectCommand="SELECT 作者代號, 作者姓名,性別,血型,聯絡電話,聯絡地址,郵遞區號,

簽約否,版稅 FROM 作者 ORDER BY 作者代號 DESC">

<DeleteParameters>

<asp:Parameter Name="作者代號" Type="String" />

</DeleteParameters>

<UpdateParameters>

<asp:Parameter Name="作者姓名" Type="String" />

<asp:Parameter Name="性別" Type="String" />

<asp:Parameter Name="血型" Type="Int16" />

<asp:Parameter Name="聯絡電話" Type="String" />

<asp:Parameter Name="聯絡地址" Type="String" />

<asp:Parameter Name="郵遞區號" Type="String" />

<asp:Parameter Name="簽約否" Type="Boolean" />

<asp:Parameter Name="版稅" Type="Double" />

<asp:Parameter Name="作者代號" Type="String" />

</UpdateParameters>

<InsertParameters>

<asp:FormParameter Name="作者代號" FormField="txtAuthorID" Type="String" />

<asp:FormParameter Name="作者姓名" FormField="txtName" Type="String" />

<asp:FormParameter Name="性別" FormField="ddlGender" Type="String" />

<asp:FormParameter Name="血型" FormField="ddlBloodType" Type="Int16" />

Page 20: CH07 P126 - Gotop

7-54

<asp:FormParameter Name="聯絡電話" FormField="txtPhone" Type="String" />

<asp:FormParameter Name="聯絡地址" FormField="txtAddress" Type="String" />

<asp:FormParameter Name="郵遞區號" FormField="txtZipCode" Type="String" />

<asp:FormParameter Name="簽約否" FormField="ddlContract" Type="Int16" />

<asp:FormParameter Name="版稅" FormField="txtRoyalty" Type="String" />

</InsertParameters>

</asp:SqlDataSource>

此外,您還必須替「新增資料」按鈕的 Click 事件處理常式撰寫下列程式碼,

以便呼叫 SqlDataSource 控制項的 Insert 方法來執行新增作業:

protected void btnInsert_Click(object sender, EventArgs e)

{

try

{

this.SqlDataSource2.Insert();

this.lblMessage.Text = "成功新增資料";

}

catch (Exception ex)

{

this.lblMessage.Text = ex.Message;

}

}

7-10 善用使用者設定檔參數

圖表 7-47 請於此輸入提供參數值之

設定檔屬性的名稱

Page 21: CH07 P126 - Gotop

7-55

您可以使用目前之使用者設定檔(Profile)的屬性值來做為 SqlDataSource

控制項的參數值。欲達此目的,請如圖表 7-47 所示,從「參數來源」下拉

式清單方塊中選取 Profile 選項(此舉表示建立一個 ProfileParameter 物

件),然後於 PropertyName 文字方塊中鍵入提供參數值之設定檔屬性的名

稱(此舉表示設定 ProfileParameter 物件的 PropertyName 屬性),並視需

要進行其他各項設定。

圖表 7-48

Page 22: CH07 P126 - Gotop

7-56

範例 示範結合使用者設定檔參數來新增資料

圖表 7-48 是網頁範例 CH7_DemoForm012.aspx 的執行畫面,當您輸入書評

文字並按下「新增書評」按鈕,就會將您所撰寫的書籍評論新增至「無責任

書評」資料表,重點是,「姓名」欄位的內容會固定是“匿名者”。相關設

計技巧說明如下:

儲存至「姓名」欄位的內容其實是取自一個名稱為 YourName 的使用

者設定檔屬性,其預設值正是“匿名者”。相關定義撰寫於組態檔

Web.config 中,列示如下:

<system.web>

<profile enabled="true">

<properties>

<add name="YourName" defaultValue="匿名者"/>

</properties>

</profile>

...

...

</system.web>

以下我們重點列出網頁範例 CH7_DemoForm012.aspx 的標記內容,請

特別注意 SqlDataSource 控制項之 InsertCommand 屬性的設定值,我

們將其 INSERT 陳述式中的參數 @姓名 定義為一個使用者設定檔參

數,而且其值將由名稱為 YourName 的使用者設定檔屬性來提供。這

也就是為什麼每當使用者新增一則書評時,「姓名」欄位的內容會固定

是“匿名者”:

<asp:FormView ID="frmCommentBook" DataSourceID="srcCommentBook"

DefaultMode="Insert" runat="server">

<InsertItemTemplate>

<asp:Label ID="lblComments" Text="請輸入您對本書的評論:" runat="server" />

<br />

<asp:TextBox ID="txtComments" Text='<%# Bind("書評") %>'

TextMode="MultiLine" Columns="50" Rows="4" runat="server" />

<br />

<asp:Button ID="btnInsert" Text="新增書評" CommandName="Insert"

runat="server" />

</InsertItemTemplate>

</asp:FormView>

Page 23: CH07 P126 - Gotop

7-57

<hr />

<asp:GridView ID="grdCommentBook" DataSourceID="srcCommentBook" runat="server" />

<asp:SqlDataSource ID="srcCommentBook"

SelectCommand="SELECT 姓名,書評,日期 FROM 無責任書評 ORDER BY 編號 DESC"

InsertCommand="INSERT 無責任書評 (姓名,書評)

VALUES (@姓名,@書評)"

ConnectionString="<%$ ConnectionStrings:chtNorthwind %>" runat="server">

<InsertParameters>

<asp:ProfileParameter Name="姓名" PropertyName="YourName" />

</InsertParameters>

</asp:SqlDataSource>

7-11 如何使用查詢字串參數

圖表 7-49

Page 24: CH07 P126 - Gotop

7-58

您可以使用查詢字串中特定欄位的值來做為 SqlDataSource 控制項的參數

值。欲達此目的,請如圖表 7-49 所示,從「參數來源」下拉式清單方塊中

選取 QueryString 選項(此舉表示建立一個 QueryStringParameter 物件),

然後於 QueryStringField 文字方塊中鍵入提供參數值之查詢字串欄位的名

稱(此舉表示設定 QueryStringParameter 物件的 QueryStringField 屬性),

並視需要進行其他各項設定。

圖表 7-50

請注意此處的查詢字串

Page 25: CH07 P126 - Gotop

7-59

範例 示範如何使用查詢字串參數來篩選出特定客戶在特定年份的

訂貨金額

圖表 7-50 是網頁範例 CH7_DemoForm013.aspx 的執行畫面,當使用者依序

選取客戶名稱與訂單年份後按下「確定」按鈕,即會以查詢字串的形式將這

兩 項 資 訊 傳 遞 給 目 標 網 頁 DemoForm013_Target.aspx , 重 點 是 ,

DemoForm013_Target.aspx 中的 SqlDataSource 控制項會使用查詢字串參數

來取得傳遞進來之查詢字串中 CustomerID 與 OrderYear 這兩個欄位的值,

以便藉以篩選出特定客戶於特定年份的訂貨金額。相關設計技巧重點說明如

下:

我們必須替網頁範例 CH7_DemoForm013.aspx 中之「確定」按鈕的

Click 事件處理常式撰寫下列程式碼,以便使用 Response.Redirect 方

法將網頁重新導向至目標網頁 DemoForm013_Target.aspx,並利用查

詢字串將客戶編號與訂單年份一併傳遞過去:

protected void btnOk_Click(object sender, EventArgs e)

{

Response.Redirect("DemoForm013_Target.aspx?CustomerID=" +

System.Web.HttpUtility.UrlEncode(this.ddlCustomerName.SelectedValue) +

"&OrderYear=" +

System.Web.HttpUtility.UrlEncode(this.ddlOrderYear.SelectedValue));

}

目標網頁DemoForm013_Target.aspx內的 SqlDataSource控制項會使用

查詢字串參數來取得傳遞進來之查詢字串中CustomerID與OrderYear

這兩個欄位的值,以便藉以篩選出特定客戶於特定年份的訂貨金額,茲

將其標記內容列示如下:

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

ConnectionString="<%$ ConnectionStrings:chtNorthwind %>"

SelectCommand="SELECT 客戶.客戶編號, 客戶.公司名稱,

Year([訂單日期]) AS 年份, Month([訂單日期]) AS 月份,

Sum([單價]*[數量]*(1-[折扣])) AS 小計

FROM (客戶 INNER JOIN 訂貨主檔 ON 客戶.客戶編號 = 訂貨主檔.客戶編號) INNER JOIN

訂貨明細 ON 訂貨主檔.訂單號碼 = 訂貨明細.訂單號碼

WHERE 客戶.客戶編號 = @CustomerID And Year([訂單日期]) = @Year

GROUP BY 客戶.客戶編號, 客戶.公司名稱, Year([訂單日期]), Month([訂單日期])

Page 26: CH07 P126 - Gotop

7-60

ORDER BY 客戶.公司名稱, Year([訂單日期]), Month([訂單日期])">

<SelectParameters>

<asp:QueryStringParameter Name="CustomerID" QueryStringField="CustomerID" />

<asp:QueryStringParameter Name="Year" QueryStringField="OrderYear" />

</SelectParameters>

</asp:SqlDataSource>

本範例另外一項值得注意的技巧,就是當您所選取的客戶並未於您所選

取的年份下任何訂單時,目標網頁 DemoForm013_Target.aspx 仍然會顯

示出該位客戶於該年份未下任何訂單的訊息(如圖表 7-51 所示)。之

所以如此,是因為我們以下列方式來設定 GridView 控制項的

EmptyDataTemplate 樣板:

圖表 7-51

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"

BackColor="White" BorderColor="#E7E7FF" BorderStyle="None"

BorderWidth="1px" CellPadding="3" DataKeyNames="客戶編號"

DataSourceID="SqlDataSource1" GridLines="Horizontal">

...

Page 27: CH07 P126 - Gotop

7-61

...

<EmptyDataTemplate>

客戶 <%=Request.QueryString["CustomerID"]%> 於

<%=Request.QueryString["OrderYear"]%> 年未下任何訂單 </EmptyDataTemplate>

...

...

</asp:GridView>

7-12 如何使用工作階段參數

圖表 7-52

您可以使用工作階段狀態( Session State )中特定項目的值來做為

SqlDataSource 控制項的參數值。欲達此目的,請如圖表 7-52 所示,從「參

數來源」下拉式清單方塊中選取 SessionField 選項(此舉表示建立一個

SessionParameter 物件),然後於 SessionField 文字方塊中鍵入提供參數值

於此鍵入工作階段項目的名稱

Page 28: CH07 P126 - Gotop

7-62

之工作階段項目的名稱(此舉表示設定 SessionParameter 物件的

SessionField 屬性),並視需要進行其他各項設定。

工作階段狀態是每一個作用 Web 應用程式工作階段之 HttpSessionState 類

別的執行個體。工作階段狀態與應用程式狀態(Application State)非常類

似,唯一的不同是工作階段狀態的適用範圍僅限於目前的瀏覽器工作階段。

如果有不同的使用者使用您的應用程式,每一位使用者都會各自擁有一個不

同的工作階段狀態。除此之外,如果同一位使用者離開您的應用程式並且在

稍後返回的話,該使用者也會擁有一個不同的工作階段狀態。

工作階段狀態是一種鍵值字典結構,用來存放需要在伺服器往返與網頁請求

之間維護的特定工作階段資訊。一旦將資料或物件存入工作階段狀態中,伺

服器就會管理它並提供給瀏覽器或用戶端裝置使用。適合儲存在工作階段狀

態變數中的資料是保存期限短、敏感、且屬於個別工作階段的資料。

圖表 7-53

使用工作階段參數查詢出本月壽星

Page 29: CH07 P126 - Gotop

7-63

範例 示範如何使用工作階段參數來查詢出本月份的壽星

圖表 7-53 是網頁範例 CH7_DemoForm014.aspx 的執行畫面,它示範如何使

用工作階段參數來查詢出本月份的壽星。相關設計技巧說明如下:

我們會替網頁的 Load 事件處理常式撰寫下列程式碼,以便於工作階段

狀態中加入一個名稱為 CurrentMonth 的項目,並將其值設定為目前的

月份:

protected void Page_Load(object sender, EventArgs e)

{

Session["CurrentMonth"] = (int)System.DateTime.Now.Month;

}

請如下所示,將 SqlDataSource 控制項之 SELECT 陳述式中的參數

@BirthdayMonth 設 定 成 一 個 工 作 階 段 參 數 , 並 且 由 名 稱 為

CurrentMonth 的工作階段項目提供其值:

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

ConnectionString="<%$ ConnectionStrings:chtNorthwind %>"

SelectCommand="SELECT 身份證字號,姓名,員工性別,出生日期,自傳

FROM 飛狐工作室 WHERE MONTH(出生日期) = @BirthdayMonth ORDER BY 自傳 DESC">

<SelectParameters>

<asp:SessionParameter Name="BirthdayMonth" SessionField="CurrentMonth"

Type="Int16" />

</SelectParameters>

</asp:SqlDataSource>