递归控制查找器将TextBox作为文字返回

时间:2012-05-09 17:14:13

标签: c# asp.net

所以我一直在使用这段代码,其中一个表单有多个用户填写的控件,例如文本框,下拉列表,单选按钮等等...并且它递归地找到它们全部和然后将结果值存储在XML文档中。但是,我遇到了一个问题,即数据库中的值(作为XML存储为每个控件作为一个单独的节点)都没有完成。在做了一些调查后,我消除了我的XML模板和数据库的配置问题。

然后我继续将调试器附加到IIS工作进程,发现递归函数出于某种原因将控件作为System.Web.UI.LiteralControl而不是Sytem.Web.UI.WebControls.TextBox返回它过去有一百万次。

ASP.NET表单:

<div class="field">
                <label>
                    <asp:RequiredFieldValidator Text="*" ID="ValidateCompanyName" runat="server" ErrorMessage="<%$ AppSettings: ValidateCompanyName %>"
                    ControlToValidate="ControlCompanyName" CssClass="requiredField" SetFocusOnError="True">
                    </asp:RequiredFieldValidator>
                    <asp:Literal ID="ControlFieldCompanyName" runat="server" Text="<%$ AppSettings: FieldCompanyName %>" />
                </label>
                <asp:TextBox ID="ControlCompanyName" runat="server" CssClass="form" />
                <br>
            </div>

递归控制功能:

public static Control FindControlRecursive(Control root, string id)
{
    if (root.ID == id)
        return root;

    foreach (Control ctl in root.Controls)
    {
        Control foundCtl = FindControlRecursive(ctl, id);

        if (foundCtl != null)
            return foundCtl;
    }

    return null;
}

我想也许它是第一个表单控件存在问题所以我在行为不当控件之前放了一个隐藏的文本框和一些默认文本......仍然没有去。然后我决定将控件的名称更改为&#34; ControlCompany&#34;它开始将它作为System.Web.UI.TextBox返回。

让我难过。

更新:http://i.stack.imgur.com/JdtiX.png

UPDATE2:它与母版页有关。从表单中删除了引用,并将递归函数更改为仅迭代Page而不是Page.Master。

FormToEmailHandler.ProcessForm(Page.Master, contactMethod, pageName, escapedEmailAddress, escapedContactName, true);

更改为:

FormToEmailHandler.ProcessForm(Page, contactMethod, pageName, escapedEmailAddress, escapedContactName, true);

public static XmlDataDocument ProcessForm(
    MasterPage master,
    string contactMethod,
    string pageName,
    string escapedEmail,
    string escapedName,
    bool processAll)

更改为:

public static XmlDataDocument ProcessForm(
    Page master,
    string contactMethod,
    string pageName,
    string escapedEmail,
    string escapedName,
    bool processAll)

更新3:

这里的XML处理代码只是为了展示它如何与递归函数集成。

public static XmlDataDocument ParseFormIntoXml(XmlDataDocument xmlTemplate, Control root)
{
    XmlNode nodeContact = xmlTemplate.SelectSingleNode("/Contact");
    if (nodeContact != null)
    {
        foreach (XmlNode thisNode in nodeContact.ChildNodes)
        {
            string controlToFind = thisNode.Name;

            switch (controlToFind)
            {
                case "DateTime":
                    thisNode.InnerText = DateTime.Now.ToString(CultureInfo.InvariantCulture);
                    break;
                case "ReferringLink":
                    thisNode.InnerText = CheckReferer(HttpContext.Current);
                    break;
                default:
                {
                    Control thisControl = FindControlRecursive(root, controlToFind);

                    if (thisControl != null)
                    {
                        string controlType = thisControl.GetType().ToString();

                        switch (controlType)
                        {
                            case "System.Web.UI.WebControls.TextBox":

                                var thisBox = (TextBox) thisControl;
                                thisNode.InnerText = thisBox.Text;

                                break;

                            case "System.Web.UI.WebControls.DropDownList":

                                var thisList = (DropDownList) thisControl;
                                thisNode.InnerText = thisList.SelectedItem.Text;

                                break;

                            case "System.Web.UI.WebControls.ListBox":

                                var thisListBox = (ListBox) thisControl;
                                thisNode.InnerText = thisListBox.SelectedValue;

                                break;

                            case "System.Web.UI.WebControls.RadioButtonList":

                                var thisRadioList = (RadioButtonList) thisControl;
                                thisNode.InnerText = thisRadioList.SelectedValue;

                                break;


                            case "System.Web.UI.WebControls.CheckBoxList":

                                var thisCheckList = (CheckBoxList) thisControl;


                                HttpContext.Current.Response.Write("<hr/>");

                                foreach (
                                    ListItem thisCheckBox in
                                        thisCheckList.Items.Cast<ListItem>().Where(
                                            thisCheckBox => thisCheckBox.Selected))
                                    thisNode.InnerText = string.Format(
                                        "{0}{1};", thisNode.InnerText, thisCheckBox.Value);

                                thisNode.InnerText = thisNode.InnerText.TrimEnd(';');

                                break;

                            case "System.Web.UI.WebControls.HiddenField":

                                var thisHidden = (HiddenField) thisControl;
                                thisNode.InnerText = thisHidden.Value;

                                break;
                        }
                    }
                }
                    break;
            }
        }
    }


    return xmlTemplate;
}

更新4:似乎是构建缓存问题。詹姆斯&#39;代码现在有效。然后我修改它不起作用......它仍然有效。

1 个答案:

答案 0 :(得分:0)

好的,我之前的错误。我的大脑今天一定不能正常运作。

首先,您的原始递归函数应该可以正常工作。我为自己是个白痴而道歉。现在获得更多信息,您遇到的问题可能与以下几个问题有关:

  1. 调用函数时,您指定了错误的根容器。控件存在的任何位置(PageMaster)应该是您开始搜索的根容器。
  2. 您提到可能存在缓存问题 - 这是有道理的,而且您很可能已经找到了正确的解决方案。
  3. 我认为在此页面上禁用缓存是有意义的,您可以通过在页面加载事件中添加以下内容来执行此操作:

    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.Cache.SetNoStore();
    

    您还可以通过向页面添加以下元标记来实现此目的:

    <meta http-equiv="Expires" CONTENT="0">
    <meta http-equiv="Cache-Control" CONTENT="no-cache">
    <meta http-equiv="Pragma" CONTENT="no-cache">
    

    这应该确保逻辑运行时应该运行。一旦我们知道逻辑一直在运行,如果您仍然遇到问题,我们需要进一步了解控件的位置与您搜索它的位置。