领先技术

了解 ASP.NET 4.0 Web 窗体和 beyond

Dino Esposito

ASP.NET 是建立丰富而强大 Web 应用程序,所以很难想象一组新引人注目的功能被添加到它的一个稳定和成熟平台。但最后一次回退,ASP.NET 3.5 为 1 的版本 Microsoft 改进该平台的内置 AJAX 支持,传送的动态数据控件通过专门用于地址的数据驱动的需求和数据输入的应用程序的组件的一个新框架增强其工作效率。

在并行,Microsoft 开发了一个全新的、 可选的编程模型调用 ASP.NET MVC。与传统的 Web 窗体模型,不同 ASP.NET MVC 帮助开发人员创建 Web 应用程序中根据广泛认可的设计模式:模型视图控制器中。
目前,在整个 ASP.NET 平台由组成的几个不同的组件:Web 窗体、 ASP.NET MVC、 动态数据控件和 ASP.NET AJAX。即将推出的 ASP.NET 4.0 平台具有相同的基础,为最新的 3.5 SP1 版本,但它提供进一步的 Web 窗体,动态数据控件在区域中的优化,最后但不容忽视 ASP.NET AJAX。

在本文中,我看一个新增和改进 Web 窗体模型中的内容。将来的列中我将地址的动态数据控件作为一个整体平台并深入探讨 ASP.NET AJAX 环境中的,开发。

一眼 ASP.NET Web 窗体 4.0

描述在整个 ASP.NET 4.0 平台中的新增的关键字是"更多的控件。既 ASP.NET 4.0 不是也革新性更改不是其现有的体系结构的一个重构。它包含,而的很多开发人员一起提供的现有框架的某些常用功能的更多控制的小规模更改。

渚嬪的方式  ASP.NET 4.0 Web 窗体使开发人员视图状态管理的更多控制在数据绑定的控件,并通过某些基于模板的控件生成的 HTML 的上下文中的生成的 ID。鍙 ﹀ 的方式  您会发现新的系列的可插接式组件没有 ASP.NET 和更好地控制通过 ScriptManager 控件的外部脚本文件的链接的早期版本中的支持提供程序 2009年模型的功能。让我们从视图状态管理中开始。

更好地控制视图状态

我说没有任何新的说明视图状态以来的一个最有争议的 ASP.NET 功能的平台出现。太多的开发人员仍被相信视图状态是浪费的带宽和每个 ASP.NET 页的不可接受的负担。几乎相同的一组开发人员尽快 welcomed ASP.NET MVC,因其完整视图状态不存在。最近,教学的 ASP.NET MVC 类,时我讨论了主/详细信息方案的用户可能客户从中选择一个要查看更多详细信息的列表。按预期的方式填充列表页中,加载时。下一步中,时处理该更改所选内容的事件,我演示如何填写客户的详细信息。但是,将用于其他选定内容列表中我还必须显式重新填充它。

学生立即注意额外工作需要在每个服务器的操作列表中填充。无法这是自动填充为 Web 窗体中吗?也,在 ASP.NET Web 窗体中您不必再次通过回发数据绑定控件填充只是由于的视图状态。

在短,视图状态不是有仅减少您的带宽。视图状态在其缓存的某些控件在页中是内容的功能在 Web 窗体模型。下一步中,ASP.NET 结构负责从视图状态还原最后一个已知的好每个控件在页中状态读取该信息。

广泛宸茬煡,但也很大程度上被忽略为视图状态是可选功能。在视图状态的支持打开的每一页默认,但开发人员有布尔属性可用于更改默认设置和不使用它。该属性命名为 EnableViewState,System.Web.UI.Control 类上定义。应该注意 System.Web.UI.Page 类从 Control 类继承。就而言,视图状态是,单个控件和页是一个和相同。

任何 ASP.NET 页的视图状态中关闭不能更容易。可以将设置 EnableViewState 为 false 以声明方式或以编程方式在页的生命周期中,如下所示:

void Page_Load(object sender, EventArgs e)
{

msdn magazine
2
Cutting Edge
// Disable viewstate for the page
// and ALL of its child controls
this.EnableViewState = false;
...
}

EnableViewState 属性指示控件是否允许缓存自己与 UI 相关的状态。提醒您在 ASP.NET 中的视图状态设置了层次结构特性,这意味着如果父控件启用视图状态,它不能禁用任何子控件上。下面的代码如果不起行为文本框中的视图状态在页级别或容器级别上启用:

protected void Page_Load(object sender, EventArgs e)
{
TextBox1.EnableViewState = false;
}

IsViewStateEnabled 属性--一个受保护的属性事实上--报告有关控件的视图状态的当前状态。 但做什么的这是否意味着所有开发人员?

如果视图状态 (这是默认设置) 页上启用,则必须关闭存储区使各个控件的状态没有方法。 要能够一定的控制它在 ASP.NET 3.5 中禁用视图状态在页级别,然后重新启用它在所需,但还将保留在记住它在层次结构特性。 具有已启用视图状态的任何容器控件将不可避免地推送其设置到其子项的列表。 这种情况稍有一个悖论产生:很可能有 IsViewStateEnabled 将设置为 true,属性和 EnableViewState 设置为 false 属性相同的控件 !

视图状态是一个基本在 ASP.NET Web 窗体体系结构,将它放完全从平台的名称是性能增益实际上不最佳选项。 年的经验已证明有一个多可持续选项默认情况下,在页上禁用视图状态。 更好,比随后使用 ASP.NET 4.0 更改:启用单个控件的视图状态控制。
在 ASP.NET 4.0,System.Web.UI.Control 类公开一个名为 ViewStateMode 的新属性:

public virtual ViewStateMode ViewStateMode { get; set; }

在属性将其可行的值从 ViewStateMode 枚举类型,的图 1 所示。

若要保留兼容性,属性的默认值是继承。但是,此属性使开发人员控制而不考虑任何父页或容器的视图状态选项的单个控件视图状态设置的可能性。

只是在 ASP.NET 页中控件的一些确实需要视图状态。渚嬪的方式  您使用简单地收集文本的所有文本框不在所有需要视图状态。如果文本是您在控件使用唯一属性,然后在 Text 属性的值将被保留的跨页回发因已过帐的值。在的视图状态中存储任何值实际上,将被定期覆盖已过帐的值。在本例中,视图状态是真正的不必要的。但有多个需要注意。被设置为创建上, 给定的非默认值,但在回发 (如只读、 背景色和等等) 过程中保持不变的任何边属性有不需要转到视图状态。渚嬪的方式  保留相同的标题在所有时间的一个按钮控件不在所有需要视图状态。ASP.NET 4.0,直到关闭单个控件视图状态是有问题。下一版本中的内容更改。这是该密钥 takeaway ViewStateMode 属性。

更好地控制自动生成的 ID

在 ASP.NET 页中中, 不允许两个服务器控件使用相同的 ID。如果这会,不会编译页--期间。在 HTML,但,它是可能的两个或多个元素共享相同的 ID。在这种情况下时通过 document.getElementById 元素搜索,您只需将得到 DOM 元素的数组。嵌套的 ASP.NET 控件呢?

大多数数据绑定的、 基于模板的控件生成相应的输出通过对每个数据绑定项重复的 HTML 模板。这意味着使用唯一的 ID 在模板中定义的任何子控件的重复多次。原始的 ID 不能只是唯一的。由于这个原因起,ASP.NET 小组定义的算法,以确保发出 ASP.NET 控件的每个 HTML 元素可能被赋予唯一的 ID。ID 导致从连接的控件 ID 命名容器的 ID。此外的情况下重复的控件 (即,模板),数字索引已为消除歧义添加。没有人确实 cared 有关该自动生成 ID 的可读性和类似于下面的字符串变得非常常见的年:

ctl00$ContentPlaceHolder1$GridView11$TextBox1

查看此,可能会注意到的第一个问题是可能的多个的元素的重复该字符串的长度使下载更大。很多重要这样的方法是从客户端脚本的角度来看有问题。预测给定控件要从客户端脚本的 ID 困难,并且会导致硬盘读取到直线的代码。在第一个位置,您需要知道详细生成一个给定的 HTML 元素埋在折叠栅格或任何其他命名容器控件的中的名称。第二个,该名称就更改为您重命名其中一个服务器控件层次结构以及的名称。以下的一个常用的技巧是:

var btn = document.getElementById("<% =Button1.ClientID %>");

这一轮包含在使用 ASP.NET 代码块插入 HTML 源代码中生成给定的控件的实际的客户端 ID。 使用主控页或基于模板的控件时, 是一个真正的 lifesaver,因为纯控件的命名容器在这种情况下结束是非常复杂的层次结构的开发人员通常保留为未命名控件。 在实际控件名称的因此,有几个自动生成的 ID。

除了使用代码块,ASP.NET 4.0 支持另一个选项:更多的控制算法生成服务器控件的客户端 ID。

System.Web.UI.Control 类现在提供了一个名为 ClientIDMode 的新属性。 该属性可以假定了几个预定义的值,如图 2 所述。

不可否认,该 ID 的生成算法尤其是当母版页涉及到不易于理解。 保证它的字符串实际上难以预测的最多生成唯一的 ID,但结束。 主要用于数据绑定控件,以便开发人员可以轻松地猜出说,Label 控件用来呈现数据的第 n 个项目上给定的属性的 ID 引入了一个更可预测的选项。 在这种情况下,您希望以反映控件 (简化到父控件命名容器结构),但也一个特定的密钥值,如为主键的层次结构 ID。 请考虑以下代码:

<asp:GridView ID="GridView1" runat="server"
ClientIDMode="Predictable"
RowClientIdSuffix="CustomerID">
...
</asp:GridView>

在这种情况下在网格的每个行由标识数据源中的一个或多个列有一个尾随的索引。 示例如下:

Panel1_GridView1_ALFKI_1

GridView 是唯一的控件以支持多个列。如果要连接的多个列则使用逗号来分隔名称。ListView 将接受仅列,而 Repeater 控件将限制记录的一个从 0 开始的索引,并接受没有列名称。

最后,请注意 ClientIDMode 属性会影响只生成的 HTML 元素的 ID 属性。设计,名称属性保持不变。

视图控件改进

大多数数据绑定控件提供了能够选择给定显示的元素--通常是一个行。在早期版本的 ASP.NET 中,所选内容被存储为在页中选定项的索引。此方法的分页的控件 (如 GridView 控件),相同所选内容对,说,一个除非以编程方式重置期间,页/更改所选内容在两个页保留的页事件。

在 ASP.NET 4.0,数据绑定控件上当前选定内容通过值跟踪您通过 DataKeyNames 属性指示在数据键字段上。要启用此功能,您将使用新 PersistSelection 布尔属性,并且将它设置为 true。默认值为 false,兼容性原因。

鍙 ﹀ 的方式  FormView 和 ListView 控件提供了一些更好地控制其生成的 HTML 标记。特别,在 FormView 现在全新 RenderTable 布尔属性的帐户。如果设置为 False (默认值为 true),再没有额外 HTML 表标记将被发送整个标记将和更方便地通过 CSS 的样式。ListView 不再需要 ASP.NET 4.0 在布局模板:

<asp:ListView ID="ListView1" runat="server">
<ItemTemplate>
<% Eval("CompanyName")%>
<hr />
</ItemTemplate>
</asp:ListView>

上述代码段足以在数据源中每个元素重复 CompanyName 列的内容。

HTML 增强

在开始,ASP.NET 未提供编程控制在 Web 页的所有可能的标记上。 时间长的网页标题丢失页类上的特殊属性。 与可以说的等 CSS 文件其他常用功能。

在 ASP.NET 4.0,Page 类公开两个新的字符串属性,以允许用户在 < 头 > 中设置某些常用标记页的节。 这两个新属性是关键字和说明。 这些服务器属性的内容将替换您可能已表明,metatags 为 HTML 文本的任何内容。

关键字和说明属性也可以直接为该 @ Page 指令,如下例所示的属性进行设置:

<%@ Page Language="C#"
AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
Keywords="ASP.NET, AJAX, 4.0"
Description="ASP.NET 4.0 Web Forms" %>

在 ASP.NET 中,调用 Response.Redirect 时, 您返回浏览器的 HTTP 302 为代码表示所请求的内容是现在可用从其他 (指定的) 的位置。基于的浏览器向指定的地址发出第二个请求就是这样。但是,搜索引擎访问您的网页的字面将 HTTP 302 代码。这是在实际意义 302 HTTP 状态代码,所请求的页已被临时移动到一个新的地址。鍥犳  搜索引擎不更新其内部的表,并重当用户单击来查看您的页中,该引擎返回原始地址。下一步中,浏览器获取一个 HTTP 302 代码,并发出第二个请求最后显示所需的页。

使整个过程的平滑,您可以利用一个全新的 ASP.NET 4.0 中重定向名为 RedirectPermanent 的方法。您使用传统的 Response.Redirect,相同的方式使用方法,只不过这一次调用方收到一个 HTTP 301 状态代码。代码 301 实际表示所请求的内容已永久移动。在浏览器,将没有最大的区别但搜索引擎的一个主要区别。

搜索引擎知道如何处理的 HTTP 301 代码,并使用该信息来更新页面的 URL 引用。下一次显示涉及在页中,搜索结果链接的 URL 是新。这种方式,用户可以迅速页和本身保存一个第二个往返。

更好地控制输出缓存

在 ASP.NET 2.0 中的 ASP.NET 运行库的几个关键部分是重构并且更加灵活和配置。这是通过引入的提供程序模型来实现。包括会话状态、 成员资格和角色管理,某些 ASP.NET 核心服务的功能已提取服务约定的排序,以便可以互换使用不同的实现给定服务的和管理员可以指示他们需要从配置文件的一个。

渚嬪的方式  旧 faithful Session 对象的实质还有其内容通过在选定的会话状态提供程序在 HttpSessionState 类的实例。默认的会话状态提供程序的进程内存中 (特别,从槽在缓存字典) 中, 获取数据,但在数据库和外部主机进程中存储数据存在的其他提供程序。

在 ASP.NET 4.0,提供程序模型包括由于某种原因被留在早期版本的 ASP.NET 的另一个非常重要的功能:输出缓存。

有许多情况是可接受的是有点过时页面响应如果这将显著的性能优点。想一下电子商务应用程序和它的一个产品目录页的一组,例如。这些页面都是相对较昂贵的创建,因为它们可能需要一个或多个数据库调用和可能是某种形式的数据连接。产品页倾向于周内保持不变,并很少会每天多次更新。为什么应该,重新生成相同的页每秒在数百次?由于 ASP.NET 1.0,输出缓存允许您缓存页响应,以便可以满足下列请求返回而不是执行页面缓存的输出。图 3 显示包括系统尝试解决请求到输出缓存中查找该步骤的应用程序事件的顺序。

目前,为止 (这按窗体可以进行分组和查询请求的 URL,或自定义字符串的字符串参数) 的任何页面输出存储在 ASP.NET 缓存的专用区域中的内存中。就在多长时间运行,输出缓存的大小会额外压力在 Web 服务器计算机上增加占用内存,并生成频繁地更新缓存的对象。在 ASP.NET 4.0,输出缓存子系统完全支持提供程序模型,从而使开发人员存储页面外 ASP.NET 工作 process.A 自定义输出缓存提供程序的响应的机会 OutputCacheProvider 派生自的类。必须在配置文件中注册类的名称,如下所示:

<caching>
<outputCache defaultProvider="AspNetInternalProvider">
<providers>
<add name="DiskCacheProvider"
type="Samples.DiskCacheProvider, MyProvider"/>
</providers>
</outputCache>
</caching>

按通常的方式方式可以有多个注册的提供程序,选择默认通过 defaultProvider 属性 outputCache 节点上。默认行为被提供通过 AspNetInternalProvider 证明是在默认提供程序,如果您不更改任何配置文件中的对象。

输出缓存提供程序不一定是相同的所有页。您可以选择提供程序提供基于每个请求或甚至特定的用户控件、 页或为页参数的组合。只要接受此指令 (页面和/或用户控件),您可以 @ OutputCache 指令中指定提供程序的名称:

<% @OutputCache Duration="3600"
VaryByParam="None"
providerName="DiskCache" %>

若要将在每个请求的基础上提供程序而,您需要重写在 global.asax,新方法,如下所示:

{
// Decide which provider to use looking at the request
string providerName = ...;
return providerName;
}

从 2.0 版开始会话状态可以存储外工作进程的内存中。 这意味着存储在 Session 对象中的任何数据必须序列化和从进程外的环境。 如果您查看回的图 3,会话状态将载入 AcquireRequestState 应用程序事件会话对象。 在内存中的内容然后返回到末尾的请求处理的存储序列化。
ASP.NET 4.0 使开发人员可以请求应用到数据流中而会话提供程序发送的某些压缩 (请参见图 4)。 压缩被获得使用 GZipStream 类而不是一个普通的 Stream 类进行任何序列化:

<sessionState mode="SqlServer" compressionEnabled="true" ... />

将可压缩您只需 compressionEnabled 属性添加到配置文件的 sessionState 部分。默认情况下, 未启用压缩。

任何 JavaScript 库是组成各种特定的 JavaScript 文件与 interconnections 的更多或更少的复杂图形。ASP.NET AJAX,而,总是试图抽象 JavaScript 从开发人员的详细信息,提供一个而不是独立的客户端 JavaScript 库,通过 ScriptManager 控件。这将在 ASP.NET 4.0 中进行更改。Microsoft AJAX 客户端库已重构,拆分为单独的文件在的图 5 中列出。图 6 显示整个库中的单个脚本文件之间的依赖项。

新的属性已被添加到 ScriptManager 控件,您可以指定应如何处理构建基块的库中。该属性是 MicrosoftAjaxMode,且 图 7 所示,它接受的值时。

更好的平台

ASP.NET 4.0 Web 窗体包含一个数小规模更改的所采取,组合在一起使其更好的开发平台。Web 窗体是一个成熟的框架,需要优化,不重新设计的。如果您不熟悉完全 Web 窗体寻找完全不同然后 ASP.NET MVC 值得注意查看。

Dino Esposito* 是一个架构师在 IDesign 和 co-author 的"Microsoft.NET:构建企业应用程序"(Microsoft 按,2008年)。基于在意大利,Esposito 是经常在世界各地的行业事件演讲者。可以在 weblogs.asp.net/despos 联接他的博客。*