ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation
2007-11-09 16:41
465 查看
ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation
一 、实现的效果我想对于ASP.NET的Validator控件已经熟悉的不能再熟悉了。我们 已经习惯了用Validator控件来验证我们在表单的输入,并通过ValidationSummary来输出我们为Validator控件设置的Error message。不知道大家有没想过进一步改进一下我们的Validation来改善我们的User Experience。比如,在ValidationSummary输出一个Link连接到对应的控件,而不是显示单纯的Error message。
比如在上图中,是一个典型的Login的Page。我们有两个必填的字段:User name和Password。为此我定义两个RequiredFieldValidator。他们的Error message分别为:”User name is mandatory!”和”Password is mandatory!”。在未输入任何值得前提下Click “Sign in”按钮,Error Message被显示在ValidationSummary上面。不过和传统的Error message不同,显示在ValidationSummary上的实际上是两个链接,Click对应的Error message,光标会设置到对应的Textbox上。比如上图所示:Click ”User name is mandatory!”,光标回到User name对应的Texbox。
二、具体实现
现在我们来简单叙述上面的效果是如果实现的,在开始之前我想说的是,方法非常简单—或许你已经猜到了:)
1.首先来看看aspx。
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<%
![](http://www.cnblogs.com/Images/dot.gif)
@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<html xmlns="http://www.w3.org/1999/xhtml">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<head id="Head1" runat="server">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<title>Login</title>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<style type="text/css">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
body{
![](http://www.cnblogs.com/Images/dot.gif)
}{font-family:Verdana; font-size:10px}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table{
![](http://www.cnblogs.com/Images/dot.gif)
}{width:300px}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table tr{
![](http://www.cnblogs.com/Images/dot.gif)
}{height:30px}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table td.firstColumn{
![](http://www.cnblogs.com/Images/dot.gif)
}{width:100px; text-align:right}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table td.secondColumn{
![](http://www.cnblogs.com/Images/dot.gif)
}{ text-align:left}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table span.asterisk{
![](http://www.cnblogs.com/Images/dot.gif)
}{color:red}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table .textbox{
![](http://www.cnblogs.com/Images/dot.gif)
}{width:150px; border:solid 1px #999999}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
table .button{
![](http://www.cnblogs.com/Images/dot.gif)
}{background-color: #00cc66;border:solid 1px #999999}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
ul li{
![](http://www.cnblogs.com/Images/dot.gif)
}{margin-bottom:5px}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
ul li a{
![](http://www.cnblogs.com/Images/dot.gif)
}{color:red; text-decoration:none}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
ul li a:hover{
![](http://www.cnblogs.com/Images/dot.gif)
}{text-decoration:underline}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
</style>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<script type="text/javascript">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
function setFocus(control)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
var controlToValidate = document.getElementById(control);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
controlToValidate.focus();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
</script>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</head>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<body style="font-family: Verdana">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<form id="form1" runat="server">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<div>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<table cellpadding="0" cellspacing="5px">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<td colspan="2">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:ValidationSummary runat="server" ID="vldLogin" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</td>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<td class="firstColumn">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
User Name: <span class="asterisk"> *</span></td>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<td class="secondColumn">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:TextBox runat="server" ID="txtUserName" CssClass="textbox"></asp:TextBox>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:RequiredFieldValidator runat="server" ID="rqfUserName" ControlToValidate="txtUserName" Display="None"></asp:RequiredFieldValidator>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:CustomValidator runat="server" ID="ctmUserName" Display="None" OnServerValidate="ctmUserName_ServerValidate" ControlToValidate="txtUserName" ></asp:CustomValidator>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</td>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<td class="firstColumn">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
Password: <span class="asterisk"> *</span></td>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<td class="secondColumn">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:TextBox runat="server" ID="txtPassword" TextMode="Password" CssClass="textbox"></asp:TextBox>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:RequiredFieldValidator runat="server" ID="rqfPassword" ControlToValidate="txtPassword" Display="None" ></asp:RequiredFieldValidator>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</td>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<td colspan="2" align="center">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:Button runat="server" ID="btnSignIn" Text="Sign in" CssClass="button" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<asp:Button runat="server" ID="ButtonCancel" Text="Cancel" CausesValidation="false"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
CssClass="button" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</td>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</tr>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</table>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</div>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</form>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</body>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</html>
在看到了上面的Screen shot之后再看看上面的Html,结构清晰得一目了然。所以我就不再进一步解释了。在这里我只需要提提定义在aspx的一段javascript function:setFocus。通过它把focus设置到指定的控件。
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
<script type="text/javascript">
![](http://www.cnblogs.com/Images/dot.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
function setFocus(control)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
var controlToValidate = document.getElementById(control);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
controlToValidate.focus();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
</script>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2.接着我们来看看code behind。
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Data;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Configuration;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.Security;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.UI;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.UI.WebControls;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.UI.WebControls.WebParts;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web.UI.HtmlControls;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public partial class Login : System.Web.UI.Page
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected void Page_Load(object sender, EventArgs e)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (this.IsPostBack)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.rqfUserName.ErrorMessage = string.Format("{0} is mandatory!", "User name");
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.rqfPassword.ErrorMessage = string.Format("{0} is mandatory!", "Password");
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.ctmUserName.ErrorMessage = "Such a user has not registered!";
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.MakeClickableErrorMessage();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void MakeClickableErrorMessage()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach (BaseValidator validator in this.Validators)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (validator.ControlToValidate == string.Empty)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
continue;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string clientID = this.FindControl(validator.ControlToValidate).ClientID;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string script = string.Format("<a href= /"javascript:setFocus('{0}');/">{1}</a>", clientID, validator.ErrorMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
validator.ErrorMessage = script;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected void ctmUserName_ServerValidate(object source, ServerValidateEventArgs args)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (this.txtUserName.Text.Trim() != "adm")
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
args.IsValid = false;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
args.IsValid = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
Code也简单得一塌糊涂,除了MakeClickableErrorMessage这个Method,其他的都不值一提。
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
private void MakeClickableErrorMessage()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach (BaseValidator validator in this.Validators)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (validator.ControlToValidate == string.Empty)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![](http://www.cnblogs.com/Images/dot.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
continue;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string clientID = this.FindControl(validator.ControlToValidate).ClientID;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string script = string.Format("<a href= /"javascript:setFocus('{0}');/">{1}</a>", clientID, validator.ErrorMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
validator.ErrorMessage = script;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
显示在ValidationSummary中原本简单的literal error message就是通过上面的这个MakeClickableErrorMessage转变成hyperlink的。在上面的code中,我遍历page中的每个Validator control。如果该Validator control有对应ControlToValidate(对于一个Validator control来说,ControlToValidate并非一个必需的property,如果没有指定该property,其值为空字符串),直接进入下一个循环。然后我把原来只是弹出的文本转变成一个<a></a>,然后再将其重新赋值给对应的Validator contorl的ErrorMessage property。
相关文章推荐
- [转贴]ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation
- ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation。(转载)
- 创建Linked ValidationSummary, 深入理解ASP.NET的Validation
- [原创]ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation
- ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation
- asp.net创建Linked ValidationSummary, 深入理解ASP.NET的Validation
- 深入理解ASP.NET的Postback
- 深入理解 ASP.NET 与客户端缓存 (Part 2 - ASP.NET 支持)
- 深入理解ASP.NET的内部运行机制
- 深入理解ASP.NET的内部运行机制
- 捕获asp.net ValidationSummary 控件消息。
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
- 深入理解 ASP.NET 动态控件 (Part 2 - 编译过程)
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
- 深入理解Asp.Net中WebForm的生命周期
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
- 深入理解 ASP.NET 动态控件 (Part 3 - 页面生命周期)
- 深入理解asp.net里的IHttpHandler
- How to use ValidationSummary control in asp.net
- 深入理解asp.net里的IHttpHandler