ASP.NET 动态数据基架和网页模板概述

更新:2007 年 11 月

显示和编辑数据是软件开发中的一项周期性任务。ASP.NET 动态数据使您只需少量代码或者不需代码即可创建数据驱动的应用程序。基架机制是动态数据中的一项重要功能,使您能够快速生成这些应用程序。

本主题包括:

  • 基架

  • 网页模板

基架

基架是一种机制,可以基于数据模型动态显示页面,而不需要幕后的物理页,从而具有现有 ASP.NET 页框架的强大功能并对这些功能进行了改进。

使用基架机制的优点包括:

  • 只需少量代码或者不需代码即可创建数据驱动的 Web 应用程序。

  • 可缩短开发时间。

  • 页面具有完整功能。其中包括所有数据库操作(查看、插入、编辑和删除)以及排序和分页功能。

  • 可基于数据库架构进行内置数据验证。

  • 可针对每个外键或布尔字段创建自动筛选器。

动态数据使用 URL 路由来匹配和处理请求。基架机制可以推断用户希望从请求的 URL 看到的视图和表。使用路由机制的好处是请求的 URL 不必与应用程序中的物理路径匹配。

启用基架机制

默认情况下,基架机制处于禁用状态。启用基架机制时应谨慎,因为这会带来安全风险,原因是基架机制会为显示、编辑、插入以及删除等功能公开整个数据模型。

可以使用下以方法来启用基架机制:

您需要注册将使用动态数据功能的数据上下文,即便不打算使用基架机制也是如此。注册是使用 RegisterContext 方法在 global.asax 文件中进行的。RegisterContext 方法将 ContextConfiguration 对象作为一个参数来接受。为了在注册数据上下文时启用基架机制,需要将 ContextConfiguration 对象的 ScaffoldAllTables 属性设置为 true。这样将会对整个数据模型启用基架机制。也就是说,它将为显示、编辑、插入以及删除等功能公开数据模型中的所有表。如果必须在基架机制中隐藏某些表,则可以使用 ScaffoldTableAttribute 属性来实现此目的。

下面的示例演示如何在为 AdventureWorksLT 数据库注册数据上下文时对数据模型中的所有表启用基架机制。

model.RegisterContext(GetType(AdventureWorksLTDataContext), _
                      New ContextConfiguration() With {.ScaffoldAllTables = True})
model.RegisterContext(typeof(AdventureWorksLTDataContext),
    new ContextConfiguration() { ScaffoldAllTables = true });

如果希望对要公开哪些表具有更多控制权,则可以使用 ScaffoldTableAttribute 属性来对给定表启用或禁用基架机制。您可以只公开应用程序需要的数据,而不是公开整个数据模型并隐藏不必公开的表。若要应用 ScaffoldTableAttribute 属性,您必须创建一个与数据模型中的实体类同名的分部类,然后将该属性应用于分部类。

下面的示例演示如何对单个表启用基架机制。

Imports System.ComponentModel.DataAnnotations

<ScaffoldTable(True)> _
Partial Public Class Product
End Class
using System.ComponentModel.DataAnnotations;

[ScaffoldTable(true)]
public partial class Product {
}

如果希望对要公开哪些数据字段具有更多控制权,则可以使用 ScaffoldColumnAttribute 属性来对给定数据字段启用或禁用基架机制。

默认情况下,并非所有数据字段都通过动态数据来显示。下面是动态数据用来决定显示或不显示某一数据字段时所使用的一些重要规则:

  • 如果 ScaffoldColumnAttribute 属性应用到了该数据字段,则会显示该数据字段。此规则会覆盖以下所有规则:

  • 如果 UIHintAttribute 属性应用到了该数据字段,则会显示该数据字段。此规则会覆盖以下所有规则:

  • 如果数据字段是外键字段,则不会显示该数据字段。这是因为动态数据会以不同方式来处理外键字段,通常不会显示外键字段值。

  • 如果数据字段是在数据库中自动生成的,则不会显示该数据字段。通常,这些类型的字段不包含相关信息。如果必须显示该数据字段,请确保已将 UIHintAttribute 属性应用到了该数据字段。

如果 IsCustomProperty 属性的值为 true,则不会显示该数据字段。

若要应用 ScaffoldColumnAttribute 属性,您必须创建一个关联的元数据类,您将在此类中将 ScaffoldColumnAttribute 属性应用于该数据字段,并且您还必须创建一个与数据模型中的实体类同名的分部类。然后,必须将这两个类关联起来,方法为将 MetadataTypeAttribute 属性应用于分部类来。

下面的示例演示如何在基架机制中隐藏特定的数据字段、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 动态数据基架机制使用模板来提供数据的默认视图。模板是常规 ASP.NET 页面,这意味着您可以更改模板以及影响 Web 应用程序中生成页的外观和行为。

创建 ASP.NET 动态数据应用程序时,项目模板会向您的项目中添加一个 DynamicData 文件夹。下表列出了动态数据提供的网页模板,它们位于 DynamicData\PageTemplates 文件夹中:

网页模板名称

说明

Details.aspx

为数据库中的单行提供详细视图。它使用 DetailsView 控件显示数据。这是用于选择操作的默认模板。

Edit.aspx

提供用于编辑数据库表中单行的界面。它使用 DetailsView 控件编辑数据。这是用于编辑操作的默认模板。

Insert.aspx

提供用于将单行插入数据库表中的界面。它使用 DetailsView 控件插入数据。这是用于插入操作的默认模板。

List.aspx

显示数据库表中的一系列行。它提供用于筛选每个外键数据或布尔列数据、排序以及分页等功能的 DropDownList 控件。它对这一系列行使用 GridView 控件。这是用于显示操作的默认模板。

ListDetails.aspx

显示数据库表中的一系列行。它提供用于筛选每个外键数据或布尔列数据、排序以及分页等功能的 DropDownList 控件。此模板对这一系列行使用 GridView 控件,对选定的行以及插入新记录操作使用 DetailsView 控件。这是一个可提供一体化功能的模板。默认情况下不使用此模板,但是您可以通过更改 Global.asax 文件中的配置来改为使用此模板。

动态数据提供的所有默认模板共同具有以下功能:

自定义网页模板

动态数据使您能够自定义提供的模板。可通过以下两种方法来实现自定义:

  • 自定义内置网页模板。

  • 自定义特定表的布局。

可通过更改位于 DynamicData\PageTemplates 文件夹中的页面来自定义内置网页模板。您在此位置所做的更改,会影响 Web 应用程序中使用基架机制的生成页的外观和行为。

可以对特定表使用基架机制并创建自定义页。为此,您必须在 DynamicData\CustomPages 文件夹下创建一个与数据模型中的实体表同名的文件夹。在此新文件夹下,添加一个与全局使用的网页模板同名的页。例如,如果希望为某个表创建一个特定的详细信息页,请将该页命名为 Details.aspx。您可以使用内置网页模板作为自定义页的起点。有关示例,请参见如何:使用自定义网页模板自定义单个表的布局

自定义路由

如上所述,动态数据使用 ASP.NET 路由来匹配和处理 URL 请求。路由是在 global.asax 文件中定义的。默认情况下,动态数据对每个操作(显示、选择、编辑和插入)使用不同的网页模板。删除功能在“列表”和“详细信息”页中均会显示,这是因为对于删除操作您不需要特定的网页模板。

您不但可以自定义路由以显示不同的 URL,而且您还可以使用它们来指定不同的网页模板、从 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
});

还可以为特定表创建特定路由,方法是指定一个与其余表所用网页模板不同的网页模板。路由的分析顺序与其定义顺序相同。必须先定义多个特定路由,然后再定义一般路由。

下面的示例演示如何为 AdventureWorks 数据库的 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
});

请参见

概念

ASP.NET 动态数据概述

ASP.NET 路由