0

所以我一直在使用这段代码一段时间,其中一个表单有多个用户填写的控件,例如,文本框、下拉列表、单选按钮等......它递归地找到它们,然后存储结果值在 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;
}

我想也许它是第一个表单控件存在问题,所以我在行为不端的控件之前放置了一个隐藏的文本框,并带有一些默认文本......仍然不行。然后我决定将控件的名称更改为“ControlCompany”,并开始将其作为 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:似乎是构建缓存问题。詹姆斯的代码现在可以工作了。然后我修改它不工作......它仍然有效。

4

1 回答 1

0

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

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

  1. 您在调用该函数时指定了错误的根容器。控件所在的位置 ( Page, Master) 应该是您开始搜索的根容器。
  2. 您提到可能存在缓存问题 - 这是有道理的,而且您很可能已经找到了正确的解决方案。

我认为禁用此页面上的缓存是有意义的,您可以通过在页面加载事件中添加以下内容来做到这一点:

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

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

于 2012-05-09T20:13:42.347 回答