ASP.NET 動態資料 Scaffolding 和頁面範本概觀
更新:2007 年 11 月
在軟體開發過程中會需要不斷地重複顯示與編輯資料。ASP.NET Dynamic Data 可以讓您只需要利用極少的程式碼或是根本不使用程式碼,建立資料導向的應用程式。Scaffolding 機制在動態資料中是不可或缺的重要功能,因為其可以讓您快速地產生這些應用程式。
這個主題包含:
Scaffolding
網頁範本
Scaffolding
Scaffolding 這一種機制會利用現有 ASP.NET 網頁架構提供之強大優點與功能,同時,透過資料模型動態顯示網頁而不是利用幕後實體網頁的方式,藉此增強這個架構。
使用 Scaffolding 機制的優點包括下列各項:
利用極少的程式碼或是根本不使用程式碼,建立資料導向的 Web 應用程式。
加速開發時程。
功能完備的網頁。這點包括所有的資料庫作業 (檢視、編輯、插入與刪除) 以及排序和分頁功能。
根據資料庫結構描述的內建資料驗證。
建立外部索引鍵或布林值欄位的自動篩選功能。
動態資料會利用 URL 路由比對與處理要求。Scaffolding 機制會推測出使用者希望從 URL 要求中看到的檢視及資料表。使用路由機制的優點是 URL 要求不需要在應用程式中比對實體路徑。
啟用 Scaffolding 機制
根據預設,Scaffolding 機制為關閉狀態。因為 Scaffolding 機制會公開整個顯示、編輯、插入與刪除功能的資料模型,因而造成安全性風險,所以啟用 Scaffolding 機制時,必須謹慎處理。
您可以透過下列方法啟用 Scaffolding 機制:
在資料內容註冊中啟用。
使用 ScaffoldTableAttribute 屬性。
使用 ScaffoldColumnAttribute 屬性。
即使沒有使用 Scaffolding 機制的打算,您也應該要註冊會使用動態資料功能的資料內容。這項註冊可以透過使用 RegisterContext 方法在 global.asax 檔案中完成。RegisterContext 方法接受 ContextConfiguration 物件做為參數使用。若要在註冊資料內容時啟用 Scaffolding 機制,請將 ContextConfiguration 物件的 ScaffoldAllTables 屬性設為 true。您可以啟用整個資料模型的 Scaffolding 機制:換言之,這麼做時,會在使用顯示、編輯、插入與刪除功能時,公開資料模型中的所有資料表。如果必須在 Scaffolding 機制中隱藏某些資料表,可以使用 ScaffoldTableAttribute 屬性進行設定。
在下列範例中,示範了如何在註冊 AdventureWorksLT 資料庫的資料內容時,針對資料模型中的所有資料表啟用 Scaffolding 機制。
model.RegisterContext(GetType(AdventureWorksLTDataContext), _
New ContextConfiguration() With {.ScaffoldAllTables = True})
model.RegisterContext(typeof(AdventureWorksLTDataContext),
new ContextConfiguration() { ScaffoldAllTables = true });
如果希望可以對已公開的資料表擁有更多的掌控,可以透過 ScaffoldTableAttribute 屬性啟用或停用特定資料表的 Scaffolding 機制。您可以只公開應用程式所需要的資料表,而不需要公開整個資料模型,然後再隱藏不必要的資料表。若要套用 ScaffoldTableAttribute 屬性,必須建立其名稱與資料模型中實體類別名稱相同的部分類別,然後將該屬性套用到部分類別。
在下列範例中,示範了如何針對個別資料表啟用 Scaffolding 機制。
Imports System.ComponentModel.DataAnnotations
<ScaffoldTable(True)> _
Partial Public Class Product
End Class
using System.ComponentModel.DataAnnotations;
[ScaffoldTable(true)]
public partial class Product {
}
如果希望可以對已公開的資料欄位擁有更多的掌控,可以透過 ScaffoldColumnAttribute 屬性啟用或停用特定資料欄位的 Scaffolding 機制。
根據預設,動態資料不會顯示所有的資料欄位。動態資料在決定是否顯示某一資料欄位時,會利用以下的一些重要規則:
如果 ScaffoldColumnAttribute 屬性已經套用到資料欄位,則會顯示資料欄位。這項規則覆寫下列所有的規則。
如果 UIHintAttribute 屬性已經套用到資料欄位,則會顯示資料欄位。這項規則覆寫下列所有的規則。
如果資料欄位為一外部索引鍵欄位,則不會顯示資料欄位。這是因為動態資料會以不同的方式處理外部索引鍵欄位,而且通常不會顯示外部索引鍵的值。
如果資料欄位會在資料庫中自動產生,則不會顯示資料欄位。這類欄位通常不會包含相關資訊。如果必須顯示資料欄位,請務必確認 UIHintAttribute 屬性已經套用到資料欄位。
如果 IsCustomProperty 屬性的值為 true,則不會顯示資料欄位。
若要套用 ScaffoldColumnAttribute 屬性,必須在想要套用 ScaffoldColumnAttribute 屬性的資料欄位中,建立關聯的中繼資料類別,同時,必須建立其名稱與資料模型中實體類別名稱相同的部分類別。接著,必須在部分類別中套用 MetadataTypeAttribute 屬性,以建立兩個類別的關聯。
在下列範例中,示範了如何對 Scaffolding 機制隱藏 PasswordHash 及 PasswordSalt 這兩個特定資料欄位。
Imports System.ComponentModel.DataAnnotations
<MetadataType(GetType(Customer_Metadata))> _
Partial Public Class Customer
End Class
Public Class Customer_Metadata
<ScaffoldColumn(False)> _
Public PasswordHash As Object
<ScaffoldColumn(False)> _
Public PasswordSalt As Object
End Class
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(Customer_Metadata))]
public partial class Customer
{
}
public class Customer_Metadata
{
[ScaffoldColumn(false)]
public object PasswordHash;
[ScaffoldColumn(false)]
public object PasswordSalt;
}
網頁範本
ASP.NET Dynamic Data Scaffolding 機制會使用提供預設資料檢視的範本。這些範本都是一般的 ASP.NET 網頁,換言之,您可以變更範本,因而修改整個 Web 應用程式所產生網頁的外觀與行為。
建立 ASP.NET Dynamic Data 應用程式時,專案範本會將 DynamicData 資料夾加入到您的專案中。下表列出動態資料在 DynamicData\PageTemplates 資料夾中提供的網頁範本。
網頁範本名稱 |
說明 |
---|---|
Details.aspx |
提供資料庫中單一資料列的詳細資料檢視。它會使用 DetailsView 控制項顯示資料。這是用於選取作業的預設範本。 |
Edit.aspx |
提供在資料庫資料表中編輯單一資料列的介面。它會使用 DetailsView 控制項編輯資料。這是用於編輯的預設範本。 |
Insert.aspx |
提供在資料庫資料表中插入單一資料列的介面。它會使用 DetailsView 控制項插入資料。這是用於插入作業的預設範本。 |
List.aspx |
在資料庫資料表中顯示資料列清單。它提供的 DropDownList 控制項可以用於篩選每一個外部索引鍵或布林值資料行的資料,並且提供排序及分頁功能。它會使用 GridView 控制項以顯示資料列清單。這是用於顯示作業的預設範本。 |
ListDetails.aspx |
在資料庫資料表中顯示資料列清單。它提供的 DropDownList 控制項可以用於篩選每一個外部索引鍵或布林值資料行的資料,並且提供排序及分頁功能。這個範本會使用 GridView 控制項以顯示資料列清單,同時,使用 DetailsView 控制項以顯示選取的資料列並且表示插入新資料錄。這是表示 All-in-One 功能的範本。根據預設,並不會使用這個範本,不過,您可以變更 Global.asax 檔案的組態檔,改為可以使用這個範本。 |
所有動態資料提供的預設範本都有下列共通的特點:
它們都會使用根資料夾下的 Site.master 這一個主版頁面。主版頁面定義了樣式表與基本的標題,也會加入可以在網站上結合 AJAX 功能的 ScriptManager 控制項。如果為了方便您日後進行偵錯,可以將 ScriptManager 控制項的 EnablePartialRendering 屬性設為 false,關閉部分頁面更新的功能。如需詳細資訊,請參閱加入 AJAX 和用戶端功能。
每一個網頁範本都有一個 UpdatePanel 控制項,可以啟用部分呈現功能而不造成回傳。如需詳細資訊,請參閱 UpdatePanel Web 伺服器控制項宣告式語法。
每一個網頁範本都有一個 DynamicDataManager 控制項,可以將動態行為加入到目前範本現有的資料繫結資料與資料來源控制項。
自訂網頁範本
動態資料可以讓您自訂預先提供的範本。可以透過兩種方式進行自訂:
自訂內建網頁範本。
自訂特定資料表的配置。
您可以變更 DynamicData\PageTemplates 資料夾中的頁面,藉此自訂內建網頁範本。在這個位置中進行的變更,會影響整個 Web 應用程式中使用 Scaffolding 機制所產生之網頁的外觀及行為。
也可以使用 Scaffolding 機制然後建立特定資料表的自訂頁面。若要這麼做,必須在 DynamicData\CustomPages 資料夾下建立一個名稱與資料模型中實體資料表名稱相同的資料夾。然後在這個新資料夾下,新增一個頁面,命名頁面時,必須與網頁範本在全域範圍使用的名稱相同。例如,如果想要建立資料表的特定詳細資料頁面,命名頁面時,必須使用 Details.aspx。自訂頁面時,您可以從內建網頁範本開始著手。如需範例,請參閱 HOW TO:使用自訂頁面範本以自訂個別資料表的配置。
自訂路由
如先前所述,動態資料會利用 ASP.NET 路由比對與處理 URL 要求。路由定義於 global.asax 檔案中。根據預設,動態資料會以不同的網頁範本處理每一項作業 (顯示、選取、編輯與插入)。因為刪除作業不需要特定的網頁範本,所以 List 及 Details 這兩個頁面中都會顯示刪除功能。
您可以自訂多個路由,顯示不同的 URL,但是您也可以利用這些路由,指定不同的網頁範本、移除副檔名,甚至可以利用路由傳遞參數,取代使用查詢字串值的方法。如需路由的詳細資訊,請參閱 ASP.NET 路由。
在下列範例中,示範了如何指定路由而能夠只在一個網頁範本上顯示所有作業。第一個路由啟用特定資料表上某一頁面的所有作業。第二個路由可以讓頁面巡覽到一筆資料錄的詳細資料,例如,在有外部索引鍵欄位時,巡覽到關聯性資料表。
routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { _
.Action = PageAction.List, _
.ViewName = "ListDetails", _
.Model = model})
routes.Add(New DynamicDataRoute("{table}/ListDetails.aspx") With { _
.Action = PageAction.Details, _
.ViewName = "ListDetails", _
.Model = model})
routes.Add(new DynamicDataRoute("{table}/ListDetails.aspx")
{
Action = PageAction.List,
ViewName = "ListDetails",
Model = model
});
routes.Add(new DynamicDataRoute("{table}/ListDetails.aspx")
{
Action = PageAction.Details,
ViewName = "ListDetails",
Model = model
});
也可以指定不同的網頁範本,替代其他資料表所使用的範本,藉此建立特定資料表的專屬路由。分析路由時會按定義路由時的順序進行。定義路由,必須先定義特定性較高的路由,然後再定義一般性路由。
在下列範例中,示範了如何為 AdventureWorksLT 資料庫中的 Products 資料表指定不同的網頁範本,然後,再定義用於資料庫其他資料表的一般性路由。
routes.Add(New DynamicDataRoute("Products/{action}.aspx") With { _
.ViewName = "ListDetails", _
.Table = "Products", _
.Model = model})
routes.Add(New DynamicDataRoute("{table}/{action}.aspx") With { _
.Constraints = New RouteValueDictionary( _
New With {.Action = "List|Details|Edit|Insert"}), _
.Model = model})
routes.Add(new DynamicDataRoute("Products/{action}.aspx")
{
ViewName = "ListDetails",
Table = "Products",
Model = model
});
routes.Add(new DynamicDataRoute("{table}/{action}.aspx")
{
Constraints = new RouteValueDictionary(
new { action = "List|Details|Edit|Insert" }),
Model = model
});