我有一个带有两个自定义验证器的webform:
<asp:TextBox ID="txtResourceStartDate" runat="server"
CssClass="textBox mandatory dateField" />
<asp:CustomValidator ID="valResourceStartDateIsDate" runat="server"
ControlToValidate="txtResourceStartDate" Display="None"
ErrorMessage="Start date must be a valid date"
OnServerValidate="Date_ServerValidate" />
<asp:TextBox ID="txtResourceEndDate" runat="server"
CssClass="textBox mandatory dateField" />
<asp:CustomValidator ID="valResourceEndDateIsDate" runat="server"
ControlToValidate="txtResourceEndDate" Display="None"
ErrorMessage="End date must be a valid date"
OnServerValidate="Date_ServerValidate" />
<asp:CustomValidator Display="None" Text="" ID="valForStartEndDate" runat="server"
OnServerValidate="ValidateStartEndDate"
ErrorMessage="Last day must be greater than or equal to first day" />
protected void Date_ServerValidate(object source, ServerValidateEventArgs args)
{
DateTime outDate;
args.IsValid = DateTime.TryParse(args.Value, out outDate);
}
protected void ValidateStartEndDate(object sender, ServerValidateEventArgs e)
{
e.IsValid = DateTime.Parse(txtResourceEndDate.Text) >=
DateTime.Parse(txtResourceStartDate.Text);
}
问题是ValidateStartEndDate
验证器在Date_ServerValidate
验证器之前触发,因此如果日期无效,则会在DateTime.Parse
上抛出格式异常。显然,这个验证器可以在解析之前检查一个有效的日期,但我真的更喜欢有一个带有适当消息的离散验证器。
所以问题是:确定验证器触发的顺序是什么?除非我遗漏了某些东西,否则不会在标记级别声明。
答案 0 :(得分:1)
您不能指望验证器会触发某个序列,也不应该。你必须确保订单无关紧要。
所以你可以
有关页面验证的一些有趣信息:http://msdn.microsoft.com/en-us/library/aa479045.aspx
答案 1 :(得分:0)
验证控制执行顺序由ValidatorCollection
返回的Page.Validators
中的控件顺序决定。反过来,此顺序由标记中的验证控件的顺序决定,但有一些例外(例如,数据绑定控件中的验证器将在稍后添加到集合中,因此将在结束时添加)。
如果您在按钮上设置CausesValidation=false
,然后使用Page.Validate
手动触发验证,则可以使用Add
上的Remove
和ValidatorCollection
方法更改执行顺序:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) {
// move myValidator to the very end, so it executes last
Validators.Remove(myValidator);
Validators.Add(myValidator);
}
}
然后,稍后在触发控件中:
protected void myButton_Click(object sender, EventArgs e)
{
Page.Validate();
if (!Page.IsValid) { return; }
// validation passed, proceed...
}
免责声明:所有这些都是经验性的,我还没有找到MSDN文档进行备份,但它似乎有效。