數據源控件是 Microsoft Visual Studio
中引入的一種新型服務器控件
它們是數據綁定體系結構的一個關鍵部分
能夠通過數據綁定控件來提供聲明性編程模型和自動數據綁定行為
本文及此系列中的後續幾篇文章將介紹實現數據源控件的核心內容
引言
簡而言之
數據源控件概括了一個數據存儲和可以針對所包含的數據執行的一些操作
DataBound 控件通過其 DataSourceID 屬性與一個數據源控件相關聯
大多數傳統的數據存儲要麼是表格格式
要麼是分層的
數據源控件也相應地分為兩類
在此要介紹的是表格格式的數據源控件
數據源控件自身並不能發揮多大作用
所有邏輯都封裝在 DataSourceView 派生的類中
至少有一個 DataSourceView 必須實現檢索(即 SELECT)一組行的功能
它可以提供修改數據(即 INSERT
UPDATE 和 DELETE)的功能(可選)
數據綁定控件可通過各種 Can??? 屬性來檢查啟用功能集
數據源控件本身只是一個或多個唯一命名視圖的容器
依據慣例
默認視圖可以按其名稱進行訪問
也可以為空
不同視圖之間是否存在關系或者存在怎樣的關系可以根據每個數據源控件的實現情況來進行適當的定義
例如
某個數據源控件可能會通過不同的視圖對同一個數據提供不同的經篩選的視圖
或者可能會在輔助視圖中提供一組子行
可使用數據綁定控件的 DataMember 屬性來選擇某個特殊的視圖(如果該數據源控件提供了多個視圖)
請注意
Whidbey 中的所有內置數據源控件目前都不提供多個視圖
最後再介紹一點內容
數據源控件(及其視圖)會實現兩組 API
第一組 API 是就四種常用的數據操作而定義的一個抽象界面
以常規方式從任一數據綁定控件中使用
第二組是可選的
它使用其表示的域或數據存儲方面的術語來定義
通常被強類型化
且面向應用程序開發人員
示例
在這些文章中
將實現一個 WeatherDataSource
它將針對由 (英文)提供的 REST(英文)XML API 來工作
以便根據郵政編碼來檢索天氣信息
通常會首先實現派生的數據源控件
public class WeatherDataSource : DataSourceControl {
public static readonly string
CurrentConditionsViewName =
CurrentConditions
;
private WeatherDataSourceView _currentConditionsView;
private WeatherDataSourceView CurrentConditionsView {
get {
if (_currentConditionsView == null) {
_currentConditionsView = new WeatherDataSourceView(this
CurrentConditionsViewName);
}
return _currentConditionsView;
}
}
public string ZipCode {
get {
string s = (string)ViewState[
ZipCode
];
return (s != null) ? s : String
Empty;
}
set {
if (String
Compare(value
ZipCode
StringComparison
Ordinal) !=
) {
ViewState[
ZipCode
] = value;
CurrentConditionsView
RaiseChangedEvent();
}
}
}
protected override DataSourceView GetView(string viewName) {
if (String
IsNullOrEmpty(viewName) ||
(String
Compare(viewName
CurrentConditionsViewName
StringComparison
OrdinalIgnoreCase) ==
)) {
return CurrentConditionsView;
}
throw new ArgumentOutOfRangeException(
viewName
);
}
protected override ICollection GetViewNames() {
return new string[] { CurrentConditionsViewName };
}
public Weather GetWeather() {
return CurrentConditionView
GetWeather();
}
}
如您所見
基本的理念是實現 GetView 以返回一個命名視圖實例
以及實現 GetViewNames 以返回可用視圖集
在此選擇從 DataSourceControl 中派生
有一點是不易察覺的
事實上數據綁定控件要查找 IDataSource 界面
而 DataSource 控件通過實現 GetView 和 GetViewNames 來實現該界面
之所以需要界面是為了使數據源控件能夠既是表格格式又是分層的(如果可能的話)
在這種情況下從主要模型中派生並將另一個模型作為界面來實現)
其次
還允許在各種方案中轉換其他控件
以使數據源的容量加倍
另外還要注意公共 ZipCode 屬性和返回強類型化 Weather 對象的 GetWeather 方法
此 API 適合於頁面開發人員
頁面開發人員無需考慮 DataSourceControl 和 DataSourceView
下一步是實現數據源視圖本身
此特定示例僅提供了 SELECT 級功能(這只是最低要求
也是在此方案中唯一有用的功能)
private sealed class WeatherDataSourceView : DataSourceView {
private WeatherDataSource _owner;
public WeatherDataSourceView(WeatherDataSource owner
string viewName)
: base(owner
viewName) {
_owner = owner;
}
protected override IEnumerable ExecuteSelect(
DataSourceSelectArguments arguments) {
arguments
RaiseUnsupportedCapabilitiesError(this);
Weather weatherObject = GetWeather();
return new Weather[] { weatherObject };
}
internal Weather GetWeather() {
string zipCode = _owner
ZipCode;
if (zipCode
Length ==
) {
throw new InvalidOperationException();
}
WeatherService weatherService = new WeatherService(zipCode);
return weatherService
GetWeather();
}
internal void RaiseChangedEvent() {
OnDataSourceViewChanged(EventArgs
Empty);
}
}
默認情況下
DataSourceView 類從諸如 CanUpdate 等的屬性返回 false
而從 Update 和相關方法拋出 NotSupportedException
在此
在 WeatherDataSourceView 中唯一需要做的就是替代抽象的 ExecuteSelect 方法
返回包含
選定
天氣數據的 IEnumerable
在實現過程中
使用了幫助程序 WeatherService 類
該類僅使用 WebRequest 對象來查詢 (英文)
方法是使用所選的郵政編碼(這沒什麼特別的)
您可能注意到了
ExecuteSelect 被標記為受保護
數據綁定控件實際調用的是在回撥中傳遞的公共(和密封)Select 方法
Select 的實現會調用 ExecuteSelect
並調用回撥與得到的 IEnumerable 實例
這種模式非常古怪
這其中有一個原因
此系列隨後的文章中將會加以說明
請稍候
下面是該用法的示例
Zip Code: <ASP:TextBox runat=
server
id=
zipCodeTextBox
/>
<asp:Button runat=
server
onclick=
OnLookuPButtonClick
Text=
查找
/>
<hr />
<asp:FormView runat=
server
DataSourceID=
weatherDS
>
<ItemTemplate>
<asp:Label runat=
server
Text=
<%# Eval(
Temperature
當前溫度是 {
}
) %>
/>
</ItemTemplate>
</asp:FormView>
<nk:WeatherDataSource runat=
server
id=
weatherDS
ZipCode=
/>
<script runat=
server
>
private void OnLookupButtonClick(object sender
EventArgs e) {
weatherDS
ZipCode = zipCodeTextBox
Text
Trim();
}
</script>
此代碼設置了郵政編碼來響應用戶輸入
這會使數據源發出更改通知
從而使綁定的 FormView 控件執行數據綁定並更改顯示
現在
數據訪問代碼就被封裝在數據源控件中
此外
通過此模型
(英文)能夠發布一個組件
該組件還可以封裝特定於其服務的詳細信息
但願它會好用
此外
抽象的數據源界面允許 FormView 僅針對天氣數據進行工作
在下一篇文章中
將增強數據源控件的功能
使其能夠自動處理用來查詢數據的篩選值(即郵政編碼)的更改
From:http://tw.wingwit.com/Article/program/net/201311/13179.html