递归控件查找器将文本框作为文本返回
本文关键字:文本 返回 控件 查找 递归 | 更新日期: 2023-09-27 18:33:35
所以我已经使用这段代码一段时间了,其中表单具有用户填写的多个控件,例如文本框、下拉列表、单选按钮等......它以递归方式查找所有值,然后将结果值存储在 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。
这让我难倒了。
更新:https://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:似乎是构建缓存问题。詹姆斯的代码现在可以工作了。然后我修改了它以不起作用...它仍然有效。
好吧,我之前的错误。我的大脑今天一定不能正常运作。
首先,您的原始递归函数应该可以正常工作。我很抱歉是个白痴。现在有了更多信息,您遇到的问题可能与以下几件事之一有关:
- 调用函数时指定了错误的根容器。控件所在的位置(
Page
、Master
(应该是您开始搜索的根容器。 - 您提到可能存在缓存问题 - 这是有道理的,而且很可能您已经找到了正确的解决方案。
我认为在此页面上禁用缓存是有意义的,您可以通过将以下内容添加到页面加载事件来执行此操作:
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">
这应该确保逻辑在应该运行时运行。一旦我们知道逻辑在持续运行,如果你仍然遇到问题,我们需要进一步查看控件所在的位置与搜索控件的位置。