介紹
以Northwind為示例數據庫,演示Dynamic Data(動態數據)
MetaModel - 數據庫和域對象之間的映射的抽象
MetaModel.RegisterContext() - 使用指定的配置上下文注冊指定的數據上下文
Scaffold - 譯為基架。即基於數據庫架構(linq to sql 或 entity framework)生成網頁模板的機 制
ScaffoldTableAttribute(false) - 隱藏指定的表
ScaffoldColumn(false) - 隱藏指定的字段
MetadataTypeAttribute(Type metadataClassType) - 指定要與數據模型類關聯的元數據類
DynamicField - 顯示指定的動態數據字段,相當於 BoundField
DynamicControl - 通過指定的字段模板顯示指定的動態數據字段
示例
全局配置
Global.asax
<%@ Application Language="C#" %> <%@ Import Namespace="System.Web.Routing" %> <%@ Import Namespace="System.Web.DynamicData" %> <script runat="server"> public static void RegisterRoutes(RouteCollection routes) { MetaModel model = new MetaModel(); // MetaModel - 數據庫和域對象之間的映射的抽象 // MetaModel.RegisterContext(Type contextType, ContextConfiguration configuration) - 使用指定的配置上下文注冊指定的數據上下文 // contextType - 數據模型中所定義的數據上下文類型 // configuration - 相關的配置。其 ScaffoldAllTables 屬性為是否要啟用 基架,基架就是基於數據庫架構(linq to sql 或 entity framework)生成網頁模板的機制 model.RegisterContext(typeof(VS2008SP1.Business.NorthwindEntities), new ContextConfiguration() { ScaffoldAllTables = true }); // 下面的語句支持分頁模式,在這種模式下,“列表”、“詳細”、“插入” // 和“更新”任務是使用不同頁執行的。若要啟用此模式,請取消注釋下面 // 的 route 定義,並注釋掉後面的合並頁模式部分中的 route 定義。 routes.Add(new DynamicDataRoute("{table}/{action}.aspx") { Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }), Model = model }); // 下面的語句支持合並頁模式,在這種模式下,“列表”、“詳細”、“插入” // 和“更新”任務是使用同一頁執行的。若要啟用此模式,請取消注釋下面 // 的 routes,並注釋掉上面的分頁模式部分中的 route 定義。 // 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 // }); } void Application_Start(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); } </script>
1、數據驅動的 Web 應用程序
詳見源代碼中的DynamicDataSite項目。動態數據的目錄結構詳見MSDN
Scaffold.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; using System.ComponentModel; namespace VS2008SP1.Business { /**//* * Scaffold - 譯為基架。即基於數據庫架構(linq to sql 或 entity framework)生成網頁 模板的機制 * ScaffoldTableAttribute(false) - 隱藏指定的表 * ScaffoldColumn(false) - 隱藏指定的字段 * MetadataTypeAttribute(Type metadataClassType) - 指定要與數據模型類關聯的元數據類 */ [ScaffoldTable(false)] public partial class Region { // Region 表不會被路由(顯示) } [MetadataType(typeof(Customers_Metadata))] public partial class Customers { // 將 Customers 的元數據關聯到 Customers_Metadata } public class Customers_Metadata { [ScaffoldColumn(false)] public object Phone; // Phone 不會在 Customers 表中被顯示 } }
Validation.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel.DataAnnotations; using System.ComponentModel; namespace VS2008SP1.Business { [MetadataType(typeof(Products_Metadata))] public partial class Products { // entity framework 會自動生成類似 OnFieldChanging() 的部分方法 // 如果想做字段的自定義輸入驗證,則可以重寫此方法 partial void OnUnitPriceChanging(global::System.Nullable<decimal> value) { if (value > 1000) { throw new ValidationException("UnitPrice 不能大於 1000"); } } } public class Products_Metadata { // [DataType(DataType.EmailAddress)] // 指定要與數據字段關聯的附加類型的名稱 // [DisplayFormat()] // 格式化輸出 // [Range()] // 指定字段的范圍約束 // [RegularExpression()] // 正則表達式驗證 // [StringLength()] // 字段的字符長度驗證 [Required()] // 必填 [UIHint("MyDecimal")] // 使用名為 MyDecimal 的字段模板 public object UnitPrice; [DisplayName("產品名稱")] // 指定的字段所顯示的名稱。在動態數據中,查看 Products 表,其 header 將顯示為 產品名稱 [StartsWith("webabcd", ErrorMessage = "{0} 必須以 {1} 開頭")] // 應用自定義 ValidationAttribute public object ProductName { get; set; } } // 編寫一個自定義 ValidationAttribute,驗證指定字段是否是以指定的字符串開頭 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] sealed public class StartsWithAttribute : ValidationAttribute { readonly string _param; /**//// <summary> /// 構造函數 /// </summary> /// <param name="param">指定的開頭字符串</param> public StartsWithAttribute(string param) { _param = param; } /**//// <summary> /// 是否通過驗證 /// </summary> /// <param name="value">輸入值</param> /// <returns></returns> public override bool IsValid(object value) { return ((string)value).ToLower().StartsWith(this._param.ToLower()); } /**//// <summary> /// 格式化錯誤信息 /// </summary> /// <param name="name">指定的字段名</param> /// <returns></returns> public override string FormatErrorMessage(string name) { return string.Format(ErrorMessageString, name, this._param); } } }
2、以 Products 表為例,演示動態數據的應用
MyProducts.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" CodeFile="MyProducts.aspx.cs" Inherits="MyProducts" Title="以 Products 表為例,演示動態數據的應用" %> <%@ Register Assembly="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Namespace="System.Web.UI.WebControls" TagPrefix="asp" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" AutoLoadForeignKeys="true" /> <h2> 以 Products 表為例,演示動態數據的應用</h2> <asp:FormView ID="FormView1" runat="server" DataSourceID="FormDataSource" AllowPaging="True" DataKeyNames="ProductId"> <ItemTemplate> <table> <tr> <td> ProductId: </td> <td> <!--DynamicField - 顯示指定的動態數據字段 ,相當於 BoundField--> <!--DynamicControl - 通過指定的字段模板顯 示指定的動態數據字段--> <asp:DynamicControl ID="ProductId" runat="server" DataField="ProductId" /> </td> </tr> <tr> <td> ProductName: </td> <td> <asp:DynamicControl ID="ProductName" runat="server" DataField="ProductName" /> </td> </tr> <tr> <td> UnitPrice: </td> <td> <asp:DynamicControl ID="UnitPrice" runat="server" DataField="UnitPrice" /> </td> </tr> <tr> <td colspan="2"> <asp:LinkButton ID="InsertButton" runat="server" CommandName="New" CausesValidation="false" Text="New" /> <asp:LinkButton ID="EditButton" runat="server" CommandName="Edit" CausesValidation="false" Text="Edit" /> <asp:LinkButton ID="DeleteButton" runat="server" CommandName="Delete" CausesValidation="false" Text="Delete" /> </td> </tr> </table> </ItemTemplate> <EditItemTemplate> <table> <tr> <td> ProductId: </td> <td> <asp:DynamicControl ID="ProductId" runat="server" DataField="ProductId" Mode="ReadOnly" /> </td> </tr> <tr> <td> ProductName: </td> <td> <!-- UIHint - 指定字段模板,此例的字段模板 會以黃色背景顯示數據 Mode - 設置呈現模式 [System.Web.UI.WebControls.DataBoundControlMode 枚舉] DataBoundControlMode.ReadOnly - 只讀模式。默認值 DataBoundControlMode.Edit - 編輯模式 DataBoundControlMode.Insert - 插入模式 --> <asp:DynamicControl ID="ProductName" runat="server" DataField="ProductName" Mode="Edit" UIHint="YelloText" /> </td> </tr> <tr> <td> UnitPrice: </td> <td> <asp:DynamicControl ID="UnitPrice" runat="server" DataField="UnitPrice" Mode="Edit" /> </td> </tr> <tr> <td colspan="2"> <asp:LinkButton ID="UpdateButton" runat="server" CommandName="Update">Update</asp:LinkButton> <asp:LinkButton ID="CancelEditButton" runat="server" CommandName="Cancel" CausesValidation="false">Cancel</asp:LinkButton> </td> </tr> </table> </EditItemTemplate> <InsertItemTemplate> <table> <tr> <td> ProductName: </td> <td> <asp:DynamicControl ID="ProductName" runat="server" DataField="ProductName" Mode="Insert" /> </td> </tr> <tr> <td colspan="2"> <asp:LinkButton ID="InsertButton" runat="server" CommandName="Insert" Text="Insert" /> <asp:LinkButton ID="CancelInsertButton" runat="server" CommandName="Cancel" CausesValidation="false" Text="Cancel" /> </td> </tr> </table> </InsertItemTemplate> <PagerSettings Position="Bottom" Mode="NumericFirstLast" /> </asp:FormView> <asp:EntityDataSource ID="FormDataSource" runat="server" ConnectionString="name=NorthwindEntities" DefaultContainerName="NorthwindEntities" EntitySetName="Products" ContextTypeName="VS2008SP1.Business.NorthwindEntities" EnableInsert="True" EnableUpdate="True" EnableDelete="True"> </asp:EntityDataSource> </asp:Content>
本文配套源碼:http://www.bianceng.net/dotnet/201212/807.htm