2.0 中的新增功能
- 跨页发送 -- ASP.NET 2.0 允许在页之间进行回发,您可以从目标页中获取源页值。
- 向导控件 -- 通过向导控件可以轻松地向页中添加多步骤窗体项方案。
- 验证组 -- 通过验证组可对一页中的多个窗体分别进行验证。
- 焦点 API -- 通过焦点 API 可以将焦点设置在页中的任何控件上,可以指定要用于输入控件提交的默认按钮,等等。
- 编译生成提供程序 -- ASP.NET 2.0 支持编译声明性文件格式,前提是将这些文件放在 App_Code 目录中。
- 不编译页 -- 在 ASP.NET 2.0 中,可从编译过程中排除页,而在运行时进行解释。
- 确保非 ASP.NET 内容的安全 -- 在 IIS 6 下,可通过 ASP.NET 应用程序轻松地确保非 ASP.NET 文件(例如静态图像或典型 ASP 页)的安全。
- 客户端脚本功能 -- ASP.NET 2.0 提供了多种利用客户端脚本的新功能。
本节介绍了用于使用 ASP.NET 2.0 的几种新功能的提示和技巧。
跨页回发
默认情况下,ASP.NET 页中的按钮控件将回发至包含该按钮的相同页, 可以在该页中为该回发编写事件处理程序。在大多数情况下,这是期望的行为,但 有时您也希望能够发送到应用程序的其他页中。
Server.Transfer 方法可用于在页间移动,但 URL 不会更改。 而使用 ASP.NET 2.0 中的跨页发送功能可以向应用程序中的其他页激发正常 回发。然后可在目标页中访问源页中启动回发的服务器控件的值。
若要使用跨页发送,可以设置
Button、LinkButton 或 ImageButton 控件的
PostBackUrl 属性,该属性指定目标 页。然后可在目标页中访问
PreviousPage 属性,以从源页中检索值。 默认情况下,PreviousPage 属性为
Page 类型,所以必须使用
FindControl 方法访问控件。也可启用对源页的强类型访问,方法是:在目标页中将
@PreviousPageType 指令 设置为源页的虚拟路径或类型名称。 注意,如果打算将多个页发送到单个目标页,则不能使用强类型 访问器(保留不设置 PreviousPage 指令)。
C# Cross Page PostBack
跨页发送按以下方法工作:
- 跨页发送在页 1 中设置窗体操作
- 单击该按钮时,发送将从页 1 转至页 2
- 页 2 保留页 1 的视图状态
- 访问 PreviousPage 时,视图状态将重新填充为页 1 的实例
- 页 1 然后执行到 LoadComplete 阶段(呈现除外)
- 此时,页 2 可以访问页 1 中的控件值
由于执行页 1(至 LoadComplete)是为了响应跨页发送, 当请求不是跨页发送而是对页 1 的正常请求时,有时需要仅执行 该页中针对特定情形的代码。您可以使用页 1 中的
IsCrossPagePostBack 属性来处理这一情况。
if (!Page.IsCrossPagePostBack) {
// handle a normal request
}
C#
也可以回发至其他应用程序,但此时
PreviousPage 属性为空。 也可以在代码中传输,同时使用
Server.Transfer(IHttpHandler, preserveViewState) 通过 PreviousPage 属性保留视图状态。
向导控件
Wizard 控件用于在网页中创建多步骤窗体项进程。 若要指定各个步骤,请在 Wizard 控件的
WizardSteps 元素的开始标记和结束标记之间为每个项放置一个
WizardStep 对象。Wizard 控件有许多优点:
- 易于启用多步骤窗体和数据集合
- 处理导航的各个方面,线性或非线性
- 启用完成时提交或进行中提交 (AllowReturn=false)
- 控件在发送到不同步骤时自动保留视图状态
- 可以使用内置 UI,也可以通过属性或模板进行自定义
C# Wizard Control
验证组
当您要在同一页中执行单独的验证方案时,可以使用
ValidationGroup 属性。 在验证程序控件以及引起验证的按钮或其他回发控件上设置组名称。这对于
Wizard 控件、
MultiView 或数据控件(用于编辑方案)很有用。 若要启用验证组,请将应属于一个公共组的所有验证程序的这一属性设置为相同值。在窗体中
CausesValidation 设置为 true 的
Button 控件中,还应将 ValidationGroup 属性设置为单击按钮时应验证的组的名称。默认情况下,所有验证程序都位于“”组(默认组)中,以便向后兼容。
Page 对象还公开
GetValidators(“group”) 方法和
Validate(“group”) 方法, 以便于检索特定组中的验证程序集合。
Page.IsValid 反映已调用
Validate 的所有控件(累积)的有效性。
下面的示例演示 ValidationGroup 属性。若要查看该行为,请单击该页中的第一个 (Search) 按钮, 然后单击该页中的第二个按钮。请注意,每次单击时将引发一组不同的验证程序。
C# Validation Groups
焦点 API 和 DefaultButton
焦点 API 允许您以声明方式或编程方式将焦点设置到窗体中的特定控件上。可以使用
Page.SetFocus 方法传递应接收 焦点的控件的 ID,也可以直接对该控件调用
Focus 方法。 还可以将 Form 元素的
DefaultFocus 属性设置为在最初加载该页时应接收焦点的控件的 ID。 与 DefaultFocus 相似,可以将 Form 元素的
DefaultButton 属性设置为特定
Button 控件的 ID,当在窗体的任何输入控件中按 Enter 键时,应通过该
Button 控件进行提交。如果页应具有对应于当前取得焦点的输入控件的不同默认按钮,则可以将特定的 输入控件包装在一个
Panel 控件中,然后设置该 Panel 的 DefaultButton 属性。当从 Panel 内的任何输入控件中 按 Enter 键时,该输入控件都将使用 Panel 的 DefaultButton 属性提交窗体。 依赖于焦点 API 的验证功能是
SetFocusOnError,该功能在验证程序控件中进行设置,可以使第一个无效控件接收焦点。 下面的示例演示在单个窗体中使用的焦点 API、DefaultButton、DefaultFocus 和 SetFocusOnError 功能。
C# Focus API, DefaultButton, DefaultFocus, and SetFocusOnError
对于复合控件,Focus 方法将焦点设置为复合控件中默认呈现 的第一个可接收焦点的控件,但单个控件可以重写此行为,以将焦点设置在其他元素上。 此示例演示,当 DetailsView 处于编辑模式时调用 Focus 方法,焦点将置于 DetailsView 中的第一个输入控件。
C# DetailsView Focus
编译生成提供程序
ASP.NET 2.0 中的编译生成提供程序是已注册的一种类型,用于将声明性文件格式“编译”或“生成”为可在您的页中使用的格式。生成提供程序在配置中注册,并与特定的文件 扩展名关联。当具有此扩展名的文件被放置到 App_Code 目录中时,ASP.NET 将调用相应的 已注册生成提供程序来编译该文件。ASP.NET 2.0 支持几种即开即用的编译生成 提供程序,也可以创建并注册自己的类型(有关更多信息,请参考
扩展 ASP.NET 节。除了各种语言的标准类文件外,ASP.NET 中还可以自动编译 下面的声明性类型:
- .wsdl -- 生成 Web 服务代理对象
- .resx -- 生成可用于本地化的资源文件
- .xsd -- 生成强类型 DataSet 对象
不编译页
Windows 对于加载到应用程序的 DLL 数有限制, 当到达此限制时性能会降低,因此不编译页能够改进 1000 页以上的大型站点的规模调整。 设置
<%@ Page CompilationMode="Auto" %> 指令可进行条件编译,从而 在不限制代码的情况下获得规模调整优点。也可以将 CompilationMode 设置为“Never”,以永久 禁止编译页。可以在 Web.config 的
<pages/> 节中设置此属性, 以应用于应用程序中的所有页。 当不编译的页中包含用户代码时,将会引发错误。但是,仍然可以使用 声明性 ASP.NET 语法,例如数据绑定(仅限
<%# Eval %> 和
<%#Bind %>)和 表达式(例如
<%$ ConnectionStrings:Pubs %>)。
C# NoCompile page
CompilationMode 属性只适用于页, 但仍然可以使用 Code 目录中的类型(例如,页的基类)。如果不希望不编译的页访问 Code 目录中的已编译类型,请在配置中锁定此目录。
C# NoCompile page with a base class
预编译工具 aspnet_compiler.exe 是一种补充功能,通过它可以使用命令行工具 预编译整个站点,以便保护页中的知识产权(代码)并能在未进行初始 编译的情况下启用部署。
确保非 ASP.NET 文件的安全
ASP.NET 处理通常与 ASP.NET 关联的文件扩展名请求,而 IIS 处理所有其他文件扩展名请求。默认情况下, 这意味着 .aspx 和 .asmx 等常用文件扩展名由 ASP.NET 处理。此处理包括对 ASP.NET 文件的身份验证和授权。但有时, 开发人员希望非 ASP.NET 资源也由 ASP.NET 处理。通过 ASP.NET 处理非 ASP.NET 文件的一个原因是要允许 ASP.NET 身份验证和授权控制对这些类型文件的访问。
Windows Server 2003 中的 IIS6 和 ASP.NET 2.0 的组合为在处理非 ASP.NET 资源请求的过程中运行 ASP.NET 管线提供 了很大的灵活性。IIS6 支持 ASP.NET 2.0 执行身份验证和授权步骤,并支持将处理非 ASP.NET 资源的其余 步骤转交给 IIS6。例如,可以使用 ASP.NET 窗体身份验证来验证对 ASP 页的访问,使用 ASP.NET 的 Url 授权 对访问授权,并且仍然允许 ASP ISAPI 扩展 (asp.dll) 执行 ASP 页。由于 IIS6 为 ISAPI 扩展引进了新的服务器支持 功能,因此上述支持是可能的:
HSE_REQ_EXEC_URL。
假定一个目录结构同时包含 ASP 和 ASP.NET 文件。ASP.NET 页用于对登录用户进行窗体身份验证,而 ASP 页表示应用程序的其余部分。使用 IIS6 MMC,右击目录并创建应用程序(建立标准 ASP.NET 应用程序时也需要这一步骤)。创建应用程序后,单击位于“目录”属性页上的“配置”按钮。这将显示“应用程序配置“对话框。IIS6 中新增了一种称为通配符应用程序映射的功能。在“应用程序配置”对话框的底部可以配置此功能。
首先确定可处理 ASP.NET 文件(如 .aspx 文件)的 ASP.NET ISAPI 扩展的路径。通过查看“应用程序配置”对话框上半部分所显示的“应用程序扩展”列表中列出的扩展,可以找到此路径。在该列表中单击映射到 .aspx 扩展的行,并选择“编辑”按钮。在弹出的对话框中,突出显示“可执行文件”文本框中的文本,并将其复制到剪贴板中。然后取消并退出对话框。
下一步,单击位于“应用程序配置”对话框下半部分的“插入”按钮。此时将显示标题为“添加/编辑应用程序扩展映射”的对话框。在“可执行文件”文本框中,输入您前面复制到剪贴板中的 ASP.NET ISAPI 扩展的路径。最终结果 应类似于下面的屏幕快照。
单击“确定”关闭所有对话框。现在,无论何时对任何文件发出请求,都先由 ASP.NET 对该请求进行处理。如果 ASP.NET 应用程序的 web.config 已启用窗体身份验证,则未经身份验证而请求 .asp 文件时,将首先触发到为窗体身份验证配置的登录页的 重定向。用户成功登录后,他们将被重新重定向到原始的 .asp 页。现在,当通过身份验证的用户请求 .asp 页时,ASP.NET 将首先运行
FormsAuthenticationModule 以验证窗体身份验证 Cookie 是否存在并仍然有效。如果此检查通过, ASP.NET 将把 .asp 页的处理重新传递给 IIS6,此时 IIS6 将把请求继续传递给通常用于处理 .asp 页的 ISAPI 扩展。在此 情况下,扩展为 asp.dll,并且 ASP 页将完成运行。ASP.NET 将请求重新传递给 IIS6 的原因在于,非 ASP.NET 资源将在已配置
<httpHandlers> 列表中找到下面的项:
<add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />
DefaultHttpHandler 负责处理发送回 IIS6 以进行进一步处理的请求。
IIS5 和 IIS5.1 中提供了具有一些限制的相似技术。这些 IIS 版本要求,对于开发人员希望由 ASP.NET 处理的每个文件扩展,必须向前面介绍的“应用程序扩展”列表中添加到 ASP.NET ISAPI 扩展的显式映射。第二个限制是 IIS 5.x 不允许请求从 ASP.NET 传递回 IIS 5.x。因此,只有使用 GET 谓词请求的静态文件才能受到 ASP.NET 的有效保护。在 ASP.NET 管线的前半部分执行完成后(其中包括身份验证和授权),ASP.NET 将使用 优化的
StaticFileHandler 处理资源,而不是尝试将请求传递回 IIS 5.x。尝试处理 POST 谓词或请求 .asp 文件将分别导致 405(无效方法)或 403 错误(已禁止:拒绝被访问)。
客户端脚本功能
ASP.NET 2.0 包括许多依赖于浏览器中的客户端脚本的功能。例如,
Button 控件的
OnClientClick 属性允许您在此按钮被单击时以编程方式运行客户端脚本。该按钮呈现客户端
onclick 属性以及按钮自身的 Javascript。
C# ClientClick Event
有些情况下,应用程序需要在页回发至服务器后仍保留它在 浏览器中的位置。例如,如果数据项导致大型页 回发,则最终用户需要将页滚动到此前正在编辑它们的位置,才能 继续。页开发人员通过以下方法可以简单地标记窗体,以维持滚动位置: 在
@Page 指令中将
MaintainScrollPositionOnPostBack 属性设置为 true, 或在 Web.config 中进行此设置,以应用于应用程序中的所有页。
C# Maintain Scroll Position
用于控件的一个令人惊喜的新功能是“客户端回调”,该功能允许控件 向服务器执行带外请求以获取附加数据,而不发送整页。此功能 依赖于用于回调处理(通常通过 XMLHTTP)的浏览器支持,该支持由
SupportsClientCallbacks 在浏览器功能中指定。
TreeView 控件利用此功能在客户端中展开父节点时按需启用 填充树节点。
GridView 和
DetailsView 也利用此功能 在
EnableSortingAndPagingCallbacks 设置为 true 时实现分页和排序。控件通过 实现
ICallbackEventHandler 接口将自身注册为可以接收回调事件。此接口允许页调用已注册的委托,以便向客户端返回回调数据。ICallBackHandler 接口有两种方法:
RaiseCallbackEvent 和
GetCallbackResult。RaiseCallbackEvent 接受用于上下文的参数(从客户端传递的参数),该参数可用于处理事件。GetCallbackResult 返回一个字符串,该字符串表示返回给客户端的数据。此接口分为两种方法是为了 允许进行异步处理,例如,从数据源控件中检索数据。 该控件然后注册一个客户端回调函数(该函数知道如何创建要传递给服务器端委托的参数)和一个错误处理函数(当回调处理 出现错误时调用)。最后,该控件将 使用
Page.ClientScript.GetCallBackEventReference 发出对回调事件的引用。 下面的示例演示如何使用客户端回调来实现级联 DropDownList 方案。 在此情况下,页自身将实现 ICallbackEventHandler 接口,以用于演示用途。
C# CallBack Event Handlers