【问题标题】:Custom TextBox with built-in Validator: server side validation not firing具有内置验证器的自定义文本框:服务器端验证未触发
【发布时间】:2008-11-19 15:27:35
【问题描述】:

我有一个如下所示的课程:

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 加载)。

想法?

【问题讨论】:

    标签: asp.net validation custom-server-controls


    【解决方案1】:

    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" /> 
    

    【讨论】:

    • 实际上,使用您的示例作为指导对我有用的是在 base.OnInit(e) 调用之前调用 EnsureChildControls() 。谢谢!
    【解决方案2】:

    验证器必须从 BaseValidator 继承。

    【讨论】:

    • 我不是在编写自己的验证器,而是在使用RequiredFieldValidator。
    • TextBox 不是复合控件,并且您的控件不继承自 BaseValidator,因此框架将永远找不到您的验证器。您可以将控件重写为 CompositeControl 或 BaseValidator。你的实现永远不会成功。
    • 如果控件被添加到控件集合中,那么生命周期将会运行,并且验证器应该在初始化时将自身添加到 page.validators 集合中。
    • 我不想将它创建为复合控件的另一个原因是它需要与其他在 TextBox 控件上工作的组件(例如 ASP.NET AJAX 工具包中的扩展器控件)集成)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 2013-02-27
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多