[原创]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。

ExpandedBlockStart.gif ContractedBlock.gif <% @PageLanguage="C#"AutoEventWireup="true"CodeFile="Login.aspx.cs"Inherits="Login" %>
<! DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head id ="Head1" runat ="server" >
< title > Login </ title >
ExpandedBlockStart.gifContractedBlock.gif
< style type ="text/css" >
ExpandedSubBlockStart.gifContractedSubBlock.gifbody
{}{font-family:Verdana;font-size:10px}
ExpandedSubBlockStart.gifContractedSubBlock.giftable
{}{width:300px}
ExpandedSubBlockStart.gifContractedSubBlock.giftabletr
{}{height:30px}
ExpandedSubBlockStart.gifContractedSubBlock.giftabletd.firstColumn
{}{width:100px;text-align:right}
ExpandedSubBlockStart.gifContractedSubBlock.giftabletd.secondColumn
{}{text-align:left}
ExpandedSubBlockStart.gifContractedSubBlock.giftablespan.asterisk
{}{color:red}
ExpandedSubBlockStart.gifContractedSubBlock.giftable.textbox
{}{width:150px;border:solid1px#999999}
ExpandedSubBlockStart.gifContractedSubBlock.giftable.button
{}{background-color:#00cc66;border:solid1px#999999}
ExpandedSubBlockStart.gifContractedSubBlock.gifulli
{}{margin-bottom:5px}
ExpandedSubBlockStart.gifContractedSubBlock.gifullia
{}{color:red;text-decoration:none}
ExpandedSubBlockStart.gifContractedSubBlock.gifullia:hover
{}{text-decoration:underline}
</ style >

ExpandedBlockStart.gifContractedBlock.gif
< script type ="text/javascript" >
functionsetFocus(control)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
varcontrolToValidate=document.getElementById(control);
controlToValidate.focus();
}


</ script >
</ head >
< body style ="font-family:Verdana" >
< form id ="form1" runat ="server" >
< div >
< table cellpadding ="0" cellspacing ="5px" >
< tr >
< td colspan ="2" >
< asp:ValidationSummary runat ="server" ID ="vldLogin" />
</ td >
</ tr >
< tr >
< td class ="firstColumn" >
UserName:
< span class ="asterisk" > &nbsp; * </ span ></ td >
< td class ="secondColumn" >
< asp:TextBox runat ="server" ID ="txtUserName" CssClass ="textbox" ></ asp:TextBox >
< asp:RequiredFieldValidator runat ="server" ID ="rqfUserName" ControlToValidate ="txtUserName" Display ="None" ></ asp:RequiredFieldValidator >
< asp:CustomValidator runat ="server" ID ="ctmUserName" Display ="None" OnServerValidate ="ctmUserName_ServerValidate" ControlToValidate ="txtUserName" ></ asp:CustomValidator >
</ td >
</ tr >
< tr >
< td class ="firstColumn" >
Password:
< span class ="asterisk" > &nbsp; * </ span ></ td >
< td class ="secondColumn" >
< asp:TextBox runat ="server" ID ="txtPassword" TextMode ="Password" CssClass ="textbox" ></ asp:TextBox >
< asp:RequiredFieldValidator runat ="server" ID ="rqfPassword" ControlToValidate ="txtPassword" Display ="None" ></ asp:RequiredFieldValidator >
</ td >
</ tr >
< tr >
< td colspan ="2" align ="center" >
< asp:Button runat ="server" ID ="btnSignIn" Text ="Signin" CssClass ="button" /> &nbsp;&nbsp;&nbsp;
< asp:Button runat ="server" ID ="ButtonCancel" Text ="Cancel" CausesValidation ="false"
CssClass
="button" />
</ td >
</ tr >
</ table >
</ div >
</ form >
</ body >
</ html >

在看到了上面的Screen shot之后再看看上面的Html,结构清晰得一目了然。所以我就不再进一步解释了。在这里我只需要提提定义在aspx的一段javascript function:setFocus。通过它把focus设置到指定的控件。

ExpandedBlockStart.gif ContractedBlock.gif < script type ="text/javascript" >
functionsetFocus(control)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
varcontrolToValidate=document.getElementById(control);
controlToValidate.focus();
}

</ script >

2.接着我们来看看code behind。

ContractedBlock.gif ExpandedBlockStart.gif
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Collections;
usingSystem.Web;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;

publicpartialclassLogin:System.Web.UI.Page
ExpandedBlockStart.gifContractedBlock.gif
{
protectedvoidPage_Load(objectsender,EventArgse)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(this.IsPostBack)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
return;
}


this.rqfUserName.ErrorMessage=string.Format("{0}ismandatory!","Username");
this.rqfPassword.ErrorMessage=string.Format("{0}ismandatory!","Password");
this.ctmUserName.ErrorMessage="Suchauserhasnotregistered!";

this.MakeClickableErrorMessage();
}


privatevoidMakeClickableErrorMessage()
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
foreach(BaseValidatorvalidatorinthis.Validators)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(validator.ControlToValidate==string.Empty)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
continue;
}

stringclientID=this.FindControl(validator.ControlToValidate).ClientID;
stringscript=string.Format("<ahref=\"javascript:setFocus('{0}');\">{1}</a>",clientID,validator.ErrorMessage);
validator.ErrorMessage
=script;
}

}


protectedvoidctmUserName_ServerValidate(objectsource,ServerValidateEventArgsargs)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(this.txtUserName.Text.Trim()!="adm")
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
args.IsValid
=false;
return;
}


args.IsValid
=true;
}

}

Code也简单得一塌糊涂,除了MakeClickableErrorMessage这个Method,其他的都不值一提。

private void MakeClickableErrorMessage()
ExpandedBlockStart.gifContractedBlock.gif
{
foreach(BaseValidatorvalidatorinthis.Validators)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(validator.ControlToValidate==string.Empty)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
continue;
}

stringclientID=this.FindControl(validator.ControlToValidate).ClientID;
stringscript=string.Format("<ahref=\"javascript:setFocus('{0}');\">{1}</a>",clientID,validator.ErrorMessage);
validator.ErrorMessage
=script;
}

}

显示在ValidationSummary中原本简单的literal error message就是通过上面的这个MakeClickableErrorMessage转变成hyperlink的。在上面的code中,我遍历page中的每个Validator control。如果该Validator control有对应ControlToValidate(对于一个Validator control来说,ControlToValidate并非一个必需的property,如果没有指定该property,其值为空字符串),直接进入下一个循环。然后我把原来只是弹出的文本转变成一个<a></a>,然后再将其重新赋值给对应的Validator contorl的ErrorMessage property。

比如对于rqfUserNameRequiredFieldValidator来说,原来的Error message是”User name is mandatory!”,那么现在的Error message变成了:

< a href =”javascript: setFocus(‘txtUserName’);” > Usernameismandatory! </ a >

三、ASP.NET是如何实现Validation的

上面只是一个简单的小窍门,我们以这个Sample为例,来进一步介绍ASP.NET如何尽心Validation的。为了简单起见,在这里我没法讨论所有的Validator control。只介绍RequiredFieldValidator和CustomValidator这两种Validator control的处理流程。

1.Client side Validation

我们通过IE来浏览上面的Page,通过参看Source code,可以看到最后Render出来的html:

ContractedBlock.gif ExpandedBlockStart.gif
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值