如何从代码隐藏中添加输入和验证控件

How to add both input and validation control from codebehind

我在 iMIS 内置的称为 RiSE 的 CMS 中工作(我不推荐)

我正在构建一个插件类型的东西,它将允许程序后端的管理员构建联系表单。 (真的很简单吧!?!?!?)

所以,我不知道要处理什么或有多少表单输入。

该过程针对每个添加的输入

  1. 将其 "id" 添加到表单提交时要使用的列表中
  2. 根据管理员选择的选项构建输入并添加属性
  3. 添加验证器

以下代码是将输入添加到页面的部分。这个想法很简单,管理员 "creates" 输入并选择他们的选项(名称、标签、占位符、只读等)

然后代码隐藏将采用这些选项并构建输入和对应的输入验证控件。

我一直收到这个错误

Unable to find control id 'text_9d8f153' referenced by the 'ControlToValidate' property of 'val_9d8f153'.

这是文件; EmailFormTextBoxDisplay.ascx

<%@ Control Language="C#" AutoEventWireup="True" CodeBehind="EmailFormTextBoxDisplay.ascx.cs" Inherits="EmailForm.EmailFormTextBoxDisplay" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register TagPrefix="asiweb" Assembly="Asi.Web" Namespace="Asi.Web.UI.WebControls" %>

<div onprerender="buildMe" runat="server"></div>

EmailFormTextBoxDisplay.ascx.cs

using System
...
    protected void buildMe(object sender, EventArgs e)
    {
        HtmlGenericControl div = (HtmlGenericControl)sender;
        if (EmailForm.formProcessed)
        {
            div.Visible = false;
        }
        else
        {
            String id = inputEmailLabel.Replace(" ", "-") + "_" + randId;
            // add this input to the list
            EmailForm.inputs.Add(new String[]
            {
                id,
                inputType,
                inputEmailLabel
            });
            // if label is not empty, add it
            if (inputLabel != "")
            {
                HtmlGenericControl label = new HtmlGenericControl("label");
                label.InnerText = inputLabel + " ";
                label.TagName = "label";
                div.Controls.Add(label);
            }
            // build and add the input
            HtmlInputGenericControl input = new HtmlInputGenericControl("input");

            // get each setting and add attributes to the input
            input.Attributes.Add("type", inputType);
            input.Attributes.Add("id", id);
            input.Attributes.Add("placeholder", inputPlaceholder);
            if (inputValue != "") input.Attributes.Add("value", inputValue);
            if (inputDisabled) input.Attributes.Add("disabled", "disabled");
            if (inputReadOnly) input.Attributes.Add("readonly", "readonly");
            if (inputRequired)
            {
                input.Attributes.Add("required", "required");
                AsiRequiredFieldValidator required = new AsiRequiredFieldValidator();
                required.ControlToValidate = id;
                required.ID = "val_" + randId;
                required.Text = "This is Required";
                div.Controls.Add(required);
            }
            if (inputRegEx != "" && inputRegEx != null)
            {
                AsiRegularExpressionValidator regEx = new AsiRegularExpressionValidator();
                regEx.ValidationExpression = inputRegEx;
                regEx.ControlToValidate = id;
                regEx.ID = "regExVal_" + randId;
                regEx.Text = inputRegExMsg;
                div.Controls.Add(regEx);
            }

            div.Controls.Add(input);
        }
    }

我已经尝试将验证部分分解成它自己的方法,并调用第一部分(进行输入)onLoad 然后添加验证器 onPreRender 但我得到了同样的错误。

我也尝试使用 Control.AddAt(2, input) 来确保 <input /> 在验证器之前,但无济于事。

如何动态构建输入和验证?

ControlToValidate 需要您要验证的控件的服务器端 ID。您需要像这样设置控件的 ID:

input.ID = "MY_ID";

然后使用输入id进行验证:

required.ControlToValidate = input.ID;

您需要使用由 aspnet 生成的 ID 引用,而不是通过属性设置的引用。这是因为 ID 将被 aspnet 客户端重命名,所以 html 中的实际 ID 可能会变成这样 ctl00_PlaceHolder1_myID

HtmlInputGenericControl input = new HtmlInputGenericControl("input");
input.ID = id;

然后是验证器

required.ControlToValidate = input.ID;

您也可以使用 "real" aspnet 控件。

TextBox tb = new TextBox();
tb.ID = "myTextBox" + i;

RequiredFieldValidator val = new RequiredFieldValidator();
val.ControlToValidate = tb.ID;
val.ErrorMessage = "Required field";

Literal lit = new Literal();
lit.Text = "<br>";

PlaceHolder1.Controls.Add(tb);
PlaceHolder1.Controls.Add(val);
PlaceHolder1.Controls.Add(lit);