我有一个表单,表示根据某些数据库配置动态生成的调查。我有一个自定义服务器控件用于呈现调查(SurveyRenderer
),其中包含用于呈现问题的自定义服务器控件(QuestionRenderers
)。如果标记为必需,我会动态添加RequiredFieldValidators
。我将这些验证器添加到SurveyRenderer
的控件集合中。
代码的要点......
// In SurveyRenderer.CreateChildControls()...
foreach (QuestionRenderer questionRenderer in questionRenderers)
{
if (questionRenderer.Question.IsRequired)
{
Controls.Add(CreateRequiredValidator(questionRenderer));
}
}
客户端验证工作正常 - 如果有人省略了必需的问题,验证器会捕获它并且表单不会验证。但是,如果我关闭JavaScript并提交无效表单,则验证器似乎无效。
在服务器端,我正在调用Page.Validate()
并在提交按钮单击事件处理程序中检查Page.IsValid
。尽管提交了一个表格,其中所需的问题一直留空 - 在服务器端Page.IsValid
上会被客户端捕获的内容仍为True
。
// In SurveyPage.aspx...
public void btnSubmit_Click(object sender, EventArgs e)
{
Page.Validate();
if (Page.IsValid)
{
// Always get here, even though the form is not valid and would
// have been caught client-side...
}
}
我应该将验证器添加到Page的Control集合中,而不是SurveyRenderer吗?为什么它在客户端而不是服务器端工作?
更新:我的QuestionRenderer注释为:
[ValidationProperty("IsValid")]
IsValid get方法是这样的:
// QuestionRenderer.IsValid
public bool IsValid
{
get
{
EnsureChildControls();
if (Question.IsRequired && QuestionIsNotAnswered())
{
return false;
}
return true;
}
}
如果我设置断点并单步执行,我可以看到QuestionRenderer.IsValid
被解雇了。它应该返回false
。如果我细粒度并在btn_submitClick中调用:
// In SurveyPage.aspx...
public void btnSubmit_Click(object sender, EventArgs e)
{
foreach (IValidator validator in Page.Validators)
{
validator.Validate(); // this calls through to QuestionRenderer.IsValid, which returns false...
bool valIsValid = validator.IsValid; // yet this is set to True
}
}
因此,即使对QuestionRenderer.IsValid的调用返回false,validator.IsValid也是如此。也许我没有正确连线?使用[ValidationProperty("IsValid")]
还不够吗?
答案 0 :(得分:1)
实际上,验证使用Page.Validators
存储所有验证器(实际例程非常棘手) - 因此无关紧要,添加它们的位置。
BaseValidator
protected internal override void OnInit(EventArgs e)
{
base.OnInit(e);
this.Page.Validators.Add(this);
}
我会将它们留在视图中,因为您可以使用object sender
- 参数(代表验证器)来获取相关控件...
我相信,你的CreateChildControls
- 连接验证器 - 被称为迟到,所以它错过了验证阶段......
您是否可以尝试在EnsureChildControls
- 事件中致电OnLoad
,看看它是否会发生变化?
另一个机会可能是,你的验证者不可见或被禁用......
修改强>
根据您的修改,我建议您使用CustomValidator
- RequiredFieldValidator
会在每个案例中返回true
(属性为true
或{{1} }),因为它不是空的:)