所以我一直在使用这段代码一段时间,其中一个表单有多个用户填写的控件,例如,文本框、下拉列表、单选按钮等......它递归地找到它们,然后存储结果值在 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:似乎是构建缓存问题。詹姆斯的代码现在可以工作了。然后我修改它不工作......它仍然有效。