Пользовательский TextBox со встроенным валидатором: проверка на стороне сервера не запускается
У меня есть класс, который выглядит так:
public class TextField : TextBox
{
public bool Required { get; set; }
RequiredFieldValidator _validator;
protected override void CreateChildControls()
{
base.CreateChildControls();
_validator = new RequiredFieldValidator();
_validator.ControlToValidate = this.ID;
if(Required)
Controls.Add(_validator);
}
public override void Render(HtmlTextWriter tw)
{
base.Render(tw);
if(Required)
_validator.RenderControl(tw);
}
}
Некоторое время это работало во внутреннем приложении, где JavaScript всегда включен. Недавно я заметил, что вышестоящая ошибка javascript может помешать запуску валидаторов, поэтому проверка на стороне сервера должна начаться... правильно? право?
Таким образом, свойство Page.IsValid всегда возвращает true (я даже пытался явно вызвать Page.Validate() заранее).
После некоторых поисков я обнаружил, что метод init валидатора должен добавить валидатор на страницу, но из-за того, как я его создаю, я не думаю, что это когда-либо случится. Таким образом, проверка на стороне клиента работает, а проверка на стороне сервера - нет.
Я пробовал это:
protected override OnInit()
{
base.OnInit();
Page.Validators.Add(_validator); // <-- validator is null here
}
Но, конечно, валидатор здесь равен нулю (и иногда он не обязателен, поэтому его не следует добавлять)... но OnInit() очень рано для меня, чтобы принимать эти решения (свойство Required не будет загружено из ViewState например).
Идеи?
2 ответа
CreateChildControls в основном для элементов управления, которые имеют дочерние элементы. RequiredFieldValidator похож на одноуровневый элемент TextBox.
Вот код, который работает для меня:
public class RequiredTextBox : TextBox
{
private RequiredFieldValidator _req;
private string _errorMessage;
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
protected override void OnInit(EventArgs e)
{
_req = new RequiredFieldValidator();
_req.ControlToValidate = this.ID;
_req.ErrorMessage = _errorMessage;
Controls.Add(_req);
base.OnInit(e);
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
base.Render(writer);
_req.RenderControl(writer);
}
}
И вот она страница ASP.NET позади:
protected void SubmitClick(object sender, EventArgs e)
{
if(Page.IsValid)
{
// do something
}
}
А вот код ASPX:
<MyControl:RequiredTextBox runat="server" ErrorMessage="Name is required!" ID="txtName"></MyControl:RequiredTextBox>
<asp:Button ID="Btn_Submit" runat="server" Text="Submit" OnClick="SubmitClick" />