ASP.NET 2.0 中的新增服务、控件与功能概述(六)

翻译|其它|编辑:郝浩|2006-05-19 15:10:00.000|阅读 1473 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


客户端回调管理器

ASP.NET 2.0中我最喜欢的功能之一就是由新的客户端回调管理器提供的“轻量级回发”功能。在过去,ASP.NET页面必须回发给服务器才能调用服务器端代码。回发是低效的,因为它们将包含由页面控件生成的所有回发数据。它们还强制页面刷新,从而导致不雅观的闪烁。

ASP.NET 2.0引入了客户端回调管理器,它使页面无需完全回发就可以回调到服务器。回调是异步的,并且通过XML-HTTP来完成。它们不包含回发数据,并且不会强制页面刷新。(在服务器端,页面像平常一样执行至PreRender事件,但在即将呈现任何HTML之前停止。)它们确实需要支持XML-HTTP协议的浏览器(这通常意味着Microsoft Internet Explorer 5.0或更高版本)。

使用客户端回调管理器涉及三个步骤。首先,调用Page.GetCallbackEventReference以获取对某个特定函数(可以从客户端脚本中调用该函数,以执行到服务器的XML-HTTP回调)的引用。ASP.NET提供了该函数的名称和实现。其次,在客户端脚本中编写一个将在回调返回时调用的方法。方法名称是传递给GetCallbackEventReference的参数之一。第三,在页面中实现ICallbackEventHandler接口。该接口包含一个方法—RaiseCallbackEvent,当回调发生时,该方法将在服务器端调用。RaiseCallbackEvent所返回的字符串将被返回到第二步所述的方法。

图11 中的代码显示了客户端回调的工作方式,并且演示了它们的一个非常实际的用途。该页面显示了一个请求姓名和地址的窗体。在Zip Code字段中键入378xx或379xx邮政编码,然后单击Autofill按钮,City字段中将显示一个名称。值得注意的是,该页面会返回到服务器以获取城市名称,但它使用客户端回调而不是完全回发来完成此工作。在实际操作中,它可以找到某个数据库以将邮政编码转换为城市名称。请注意,该页面并不像页面在回发到服务器时通常所做的那样进行重新绘制。相反,更新是快速且简洁的!
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

<html>
<body>
<h1>Please Register</h1>
<hr>
<form runat="server">
<table>
<tr>
<td>First Name</td>
<td><asp:TextBox ID="FirstName" RunAt="server" /></td>
<td></td>
</tr>
<tr>
<td>Last Name</td>
<td><asp:TextBox ID="LastName" RunAt="server" /></td>
<td></td>
</tr>
<tr>
<td>Address 1</td>
<td><asp:TextBox ID="Address1" RunAt="server" /></td>
<td></td>
</tr>
<tr>
<td>Address 2</td>
<td><asp:TextBox ID="Address2" RunAt="server" /></td>
<td></td>
</tr>
<tr>
<td>City</td>
<td><asp:TextBox ID="City" RunAt="server" /></td>
<td></td>
</tr>
<tr>
<td>State</td>
<td><asp:TextBox ID="State" RunAt="server" /></td>
<td></td>
</tr>
<tr>
<td>Zip Code</td>
<td><asp:TextBox ID="Zip" RunAt="server" /></td>
<td><asp:Button ID="AutofillButton" Text="Autofill"
RunAt="server" /></td>
</tr>
</table>
</form>
</body>
</html>

<script language="javascript">
// Function called when callback returns
function __onCallbackCompleted (result, context)
{
    // Display the string returned by the server's RaiseCallbackEvent
    // method in the input field named "City"

    document.getElementById ('City').value = result;
}
</script>

<script language="C#" runat="server">
void Page_Load (Object sender, EventArgs e)
{
    // Get callback event reference (e.g., "__doCallback (...)")
    string cbref = GetCallbackEventReference (this,
    "document.getElementById ('Zip').value",
    "__onCallbackCompleted", "null", "null");

    // Wire the callback event reference to the Autofill button with
    // an onclick attribute (and add "return false" to event reference
    // to prevent a postback from occurring)

    AutofillButton.Attributes.Add ("onclick",
    cbref + "; return false;");
}

// Server-side callback event handler

string ICallbackEventHandler.RaiseCallbackEvent (string arg)
{
    if (arg.StartsWith ("378"))
    return "Oak Ridge";
    else if (arg.StartsWith ("379"))
    return "Knoxville";
    else
    return "Unknown";
}
</script>
                                     图11 callback.aspx

验证组
验证控件是ASP.NET 1.x中更为卓越的创新。诸如RequiredFieldValidator和RegularExpressionValidator之类的控件使开发人员能够在客户端和服务器上进行更为智能的输入验证,而不必成为客户端脚本编写和浏览器DOM方面的专家。遗憾的是,版本1.x验证控件存在一个致命的缺陷,即:没有一种比较好的方法来将这些控件组合在一起,以便页面的一个部分上的验证程序可以重写该页面其他部分上的验证程序,并且无论其他验证程序的状态如何,都可以使回发发生。

该问题由ValidationGroups1.aspx阐明,它包含在您可以针对本文下载的示例中。页面的设计者预计用户能够填写一组TextBox并回发到服务器,而不必同时填写另一个组,但它并不按此方式工作。除非所有输入字段都被填充,否则验证程序将抱怨不休,如图12所示。

                                    图12 ASP.NET 1.x中的验证控件
ASP.NET 2.0中的新验证组功能一劳永逸地解决了该问题。现在,可以使用ValidationGroup属性来组合验证控件。可以用相同的方式将按钮控件分配给组,并且当一个组中的所有验证程序都对输入感到满意时,它们才允许回发发生,当然,前提是回发是由验证程序同一组中的控件生成的。ValidationGroups2.aspx演示了该技术(参见图13)。从表面上看,该页面与ValidationGroups1.aspx完全相同。但在内部,它们却完全不同。现在,您可以填写任一组TextBox,并且通过单击TextBox验证组中的按钮进行回发。
<html>
<body>
<form runat="server">
<h1>New Users</h1>
<table>
<tr>
<td>User Name</td>
<td><asp:TextBox ID="NewUserName" RunAt="server" /></td>
<td><asp:RequiredFieldValidator ValidationGroup="NewUsers"
ControlToValidate="NewUserName" ErrorMessage="Required"
RunAt="server" /></td>
</tr>
<tr>
<td>Password</td>
<td><asp:TextBox ID="NewPassword1" TextMode="Password"
RunAt="server" /></td>
<td><asp:RequiredFieldValidator ValidationGroup="NewUsers"
ControlToValidate="NewPassword1" ErrorMessage="Required"
RunAt="server" /></td>
</tr>
<tr>
<td>Retype Password</td>
<td><asp:TextBox ID="NewPassword2" TextMode="Password"
RunAt="server" /></td>
<td><asp:RequiredFieldValidator ValidationGroup="NewUsers"
ControlToValidate="NewPassword2" ErrorMessage="Required"
RunAt="server" /></td>
</tr>
<tr>
<td>E-Mail Address</td>
<td><asp:TextBox ID="NewEMail" RunAt="server" /></td>
<td><asp:RequiredFieldValidator ValidationGroup="NewUsers"
ControlToValidate="NewEMail" ErrorMessage="Required"
RunAt="server" /></td>
</tr>
<tr>
<td></td>
<td><asp:Button ValidationGroup="NewUsers"
Text="Create Account" OnClick="OnCreateAccount"
RunAt="server" /></td>
<td></td>
</tr>
</table>
<hr>
<h1>Existing Users</h1>
<table>
<tr>
<td>User Name</td>
<td><asp:TextBox ID="UserName" RunAt="server" /></td>
<td><asp:RequiredFieldValidator
ValidationGroup="ExistingUsers"
ControlToValidate="UserName" ErrorMessage="Required"
RunAt="server" /></td>
</tr>
<tr>
<td>Password</td>
<td><asp:TextBox ID="Password" TextMode="Password"
RunAt="server" /></td>
<td><asp:RequiredFieldValidator
ValidationGroup="ExistingUsers"
ControlToValidate="Password" ErrorMessage="Required"
RunAt="server" /></td>
</tr>
<tr>
<td></td>
<td><asp:Button ValidationGroup="ExistingUsers"
Text="Log In" OnClick="OnLogIn" RunAt="server" /></td>
<td></td>
</tr>
</table>
</form>
</body>
</html>

<script language="C#" runat="server">
void OnCreateAccount (Object sender, EventArgs e) {}
void OnLogIn (Object sender, EventArgs e) {}
</script>
图13 ValidationGroups2.aspx

跨页面发送
有关ASP.NET 1.x的最多抱怨是只允许页面回发到其本身。在版本2.0中,这一点通过引入跨页面发送而得到改变。要设置跨页面发送,您需要使用导致回发发生的控件的PostBackUrl属性来指定目标页面,如PageOne.aspx中的以下代码所示:
<html>
<body>
<form runat="server">
<asp:TextBox ID="Input" RunAt="server" />
<asp:Button Text="Test" PostBackUrl="PageTwo.aspx"
RunAt="server"
/>
</form>
</body>
</html>
当被单击时,PageOne.aspx中的按钮将回发到PageTwo.aspx:
<html>
<body>
<asp:Label ID="Output" RunAt="server" />
</body>
</html>

<script language="C#" runat="server">
void Page_Load (Object sender, EventArgs e)
{
     TextBox input = (TextBox) PreviousPage.FindControl ("Input");
     Output.Text = "Hello, " + input.Text;
}
</script>
PageTwo.aspx使用Page类的新PreviousPage属性来获取对起始页面的引用。对FindControl的简单调用将返回对PageOne.aspx中声明的TextBox的引用,以便可以检索用户的输入。
默认情况下,System.Web.UI.Page.PreviousPage返回对引起回发的页面的弱类型化引用。但是,如果PageOne.aspx是唯一能够向PageTwo.aspx发送的页面,则PageTwo.aspx可以使用新的@ PreviousPageType指令来获取对PageOne.aspx的强类型化访问,如下面的代码所示:
<%@ PreviousPageType TypeName="ASP.PageOne.aspx" %>
...

小结
ASP.NET 2.0还包含其他我尚未讨论的新功能。例如,内置的站点计数器服务使您能够记录站点使用情况的统计信息,并且在Webadmin.axd中或者在您自己的自定义GUI中查看它们。新的Web组件子系统提供了一个用于构建SharePoint服务器样式门户的框架(有关ASP.NET 2.0中的Web部件和门户的详细信息,请参阅本期杂志《利用 ASP.NET 2.0 中的 Web 部件和个性化释放站点的潜能》,而集成的移动设备支持则意味着,您不再需要安装单独的工具包来使输出适合PDA及其他小型设备。对现有控件进行的无数增强使得这些控件在生成基于组件的Web页方面比以往任何时候都更加灵活。


 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP