ASP.NET 4 和 Visual Studio 2010 Web 开发概述 5 - 动态数据

动态数据是在 2008 年中在 .NET Framework 3.5 SP1 中引入的。这个特性提供了许多创建数据驱动应用程序的增强。包括:

  • 一个为快速构建数据驱动网站的 RAD 体验
  • 基于数据模型中定义的限制的自动验证
  • 通过使用字段模板轻易地在 GridView 和 DetailsView 控件中更改为字段产生标记的能力。

更多信息,参见 Dynamic Data 文档

对于 ASP.NET 4,动态数据已经对开发人员做了增强,甚至能够更加强大地快速构建数据驱动的网站。

1) 为现存项目启用动态数据

.NET Framework 3.5 SP1 中的动态数据带来了以下新特性:

  • 字段模板——这些为数据绑定控件提供了基于数据类型的模板。字段模板提供了更加简单的方法来定制数据控件的外观。
  • 验证——动态数据在数据类上使用特性(attribute)来指定验证,这些验证是为通用的场景准备的,像必填字段,范围字段,类型检查,模式匹配(使用正则表达式),和自定义验证。验证是由数据控件实施的。

然而,这些特性需要下面的要求:

  • 数据访问层必须基于实体框架(Entity Framework)或 LINQ to SQL。
  • 支持这些特性的数据源控件只有 EntityDataSource 和 LinqDataSource 控件。
  • 需要使用动态数据或动态数据实体模板创建的Web项目,才能拥有所有支持这些特性必需的文件。

在 ASP.NET 4 中动态数据的主要目标是启用对任意 ASP.NET 应用程序的动态数据新功能。下面的例子展示了在现存页面中利用动态数据功能为控件产生标记的功能:

< asp:GridView ID ="GridView1" runat ="server" AutoGenerateColumns ="True" DataKeyNames ="ProductID" DataSourceID ="LinqDataSource1" > </ asp:GridView > < asp:LinqDataSource ID ="LinqDataSource1" runat ="server" ContextTypeName ="DataClassesDataContext" EnableDelete ="True" EnableInsert ="True" EnableUpdate ="True" TableName ="Products" > </ asp:LinqDataSource >

下面的代码必须添加到页面中,才能为这些控件启用动态数据支持:

GridView1.EnableDynamicData( typeof(Product));

当 GridView 控件处于编辑状态时,动态数据会自动验证输入的数据。如果验证失败,错误消息会显示出来。

这个功能还提供了其他好处,例如能够指定插入模式的默认值。没有动态数据,想要为字段实现默认值,必须附加一个事件,定位控件(使用 FindControl),设置值。在 ASP.NET 4 中,EnableDynamicData 调用支持一个为对象的任何字段传递默认值的第二参数。例如:

DetailsView1.EnableDynamicData( typeof(Product), new { ProductName = "DefaultName" });

2) 声明式 DynamicDataManager 控件语法

DynamicDataManager 控件已经增强,所以可以声明式地配置它,就像 ASP.NET 中的大多数控件一样,而不是只能用代码。例如:

< asp:DynamicDataManager ID ="DynamicDataManager1" runat ="server" AutoLoadForeignKeys ="true" > < DataControls > < asp:DataControlReference ControlID ="GridView1" /> </ DataControls > </ asp:DynamicDataManager > < asp:GridView id ="GridView1" runat ="server" > </ asp:GridView >

这个启用了动态数据行为的标记在 DynamicDataManager 控件的 DataControls 节中被引用了。

3) 实体模板

实体模板提供了不需要创建自定义页面就能定制数据布局的新方法。页面模板使用 FormView 控件(取代旧版本使用的 DetailsView 控件)和 DynamicEntity 控件来呈现实体模板。这就能对动态数据呈现的标记有更多的控制。

下面的列表展示了新项目布局模板包含的实体模板:

\DynamicData\EntityTemplates \DynamicData\EntityTemplates\Default.ascx \DynamicData\EntityTemplates\Default_Edit.ascx \DynamicData\EntityTemplates\Default_Insert.ascx

EntityTemplate 目录包含如何显示数据模型对象的模板。默认地,对象通过使用 Default.ascx 模板呈现。下面的例子展示了 Default.ascx 控件:

< asp:EntityTemplate runat ="server" ID ="TemplateContainer1" > < ItemTemplate > < tr > < td > < asp:Label ID ="Label1" runat ="server" OnInit ="Label_Init" /> </ td > < td > < asp:DynamicControl runat ="server" OnInit ="DynamicControl_Init" /> </ td > </ tr > </ ItemTemplate > </ asp:EntityTemplate >

默认模板可以编辑来改变整个站点的外观。这些模板可以进行显示、编辑和插入操作。新模板可以基于数据对象的名称添加,这样才能只改变一种类型的对象的外观。例如,可以添加下面的模板:

\DynamicData\EntityTemplates\Products.aspx

模板可能包含下面的标记:

< tr > < td >Name </ td > < td >< asp:DynamicControl runat ="server" DataField ="ProductName" /></ td > < td >Category </ td > < td >< asp:DynamicControl runat ="server" DataField ="Category" /></ td > </ tr >

新实体模板通过使用新的 DynamicEntity 显示在页面上。在运行时,这个控件使用实体模板的内容代替。下面的标记展示了使用实体模板的 Detail.aspx 页面模板中的 FormView 控件。注意标记中的 DynamicEntity 元素。

< asp:FormView runat ="server" ID ="FormView1" DataSourceID ="DetailsDataSource" OnItemDeleted ="FormView1_ItemDeleted" > < ItemTemplate > < table class ="DDDetailsTable" cellpadding ="6" > < asp:DynamicEntity runat ="server" /> < tr class ="td" > < td colspan ="2" > < asp:DynamicHyperLink ID ="EditHyperLink" runat ="server" Action ="Edit" Text ="Edit" /> < asp:LinkButton ID ="DeleteLinkButton" runat ="server" CommandName ="Delete" CausesValidation ="false" OnClientClick ='return confirm("Are you sure you want to delete this item?");' Text ="Delete" /> </ td > </ tr > </ table > </ ItemTemplate > </ asp:FormView >

4) 为 URL 和 E-mail 地址设计的新字段模板

ASP.NET 4 引入了两个新的内置字段模板,EmailAddress.ascx 和 Url.ascx。这些模板用于使用 DataType 特性标记为 EmailAddress 或 Url 的字段。对于 EmailAddress 对象,字段作为超链接显示,并使用 mailto: 协议创建。当用户点击链接,它打开用户的 e-mail 客户端并创建一个简略的消息。作为 Url 类型的对象则以普通超链接显示。

下面的例子展示了字段如何标记。

[DataType(DataType.EmailAddress)] public object HomeEmail { get; set; } [DataType(DataType.Url)] public object Website { get; set; }

5) 使用 DynamicHyperLink 控件创建链接

动态数据使用新的路由特性(.NET Framework 3.5 SP1 加入)来控制终端用户访问网站时看到的 URL。新的 DynamicHyperLink 控件使构造到页面的链接变得容易。下面的例子展示了如何使用 DynamicHyperLink 控件:

< asp:DynamicHyperLink ID ="ListHyperLink" runat ="server" Action ="List" TableName ="Products" > Show all products </ asp:DynamicHyperLink >

6) 支持数据模型中的继承

实体框架和 LINQ to SQL 都支持数据模型中的继承。例如数据库中有一个 InsurancePolicy 表,还有两个表 CarPolicy 和 HousePolicy,这两个表拥有和 InsurancePolicy 相同的字段并添加了更多字段。动态数据已经修改为能够理解数据模型中继承的对象并支持对继承数据表的 scaffolding(这个单词怎么翻译?)。

7) 支持多对多关系(仅对实体框架)

实体框架拥有在数据表之间进行多对多关联的丰富支持,这是通过在实体对象中以集合暴露关联来实现的。新的 ManyToMany.ascx 和 ManyToMany_Edit.ascx 字段模板已经添加了对有多对多关联数据的显示和编辑的支持。

8) 对控件显示和支持枚举的新特性(Attribute)

DisplayAttribute 添加了字段如何显示的额外控制。DisplayName 特性(Attribute)在旧版本的动态数据中允许更改作为字段标题的名称。新的 DisplayAttribute 类可以指定更多关于显示字段的选项,例如字段显示的顺序和字段是否用作过滤器。The attribute also provides independent control of the name used for the labels in a GridView control, the name used in a DetailsView control, the help text for the field, and the watermark used for the field (if the field accepts text input).

EnumDataTypeAttribute 用于把字段映射到枚举。当把这个特性应用到字段时,就指定了枚举类型。动态数据使用新的 Enumeration.ascx 字段模板为显示和编辑枚举值创建 UI。模板从数据库把值映射到枚举中的值。

9) 对过滤器的增强支持

动态数据 1.0 内置对 Boolean 列和外键列的过滤器。过滤器不允许指定它们是否显示或者以什么顺序显示。新的 DisplayAttribute 同时解决了这两个问题。

另外一个增强是过滤器支持已经重写来使用 Web Forms 的新特性。这可以不需要了解过滤器使用的数据源控件就能创建过滤器。有了这些扩展,过滤器同样也已经变成了模板控件,这样就允许添加新的。最后,DisplayAttribute 类允许重写默认过滤器,以同样的方式 UIHint 允许重写列的默认字段模板。