そのため、フォームにユーザーが入力する複数のコントロール (テキスト ボックス、ドロップダウン、ラジオ ボタンなど) がある場合に、このコードをしばらく使用してきました。 XML ドキュメントで。しかし、データベース内の値 (各コントロールを個別のノードとして XML として保存) が完全ではないという問題に遭遇しました。いくつかの調査を行った後、XML テンプレートとデータベースの構成の問題を解消しました。
次に、デバッガーを IIS ワーカー プロセスにアタッチしたところ、何らかの理由で再帰関数がコントロールを System.Web.UI.LiteralControl として返していることがわかりました。過去に100万回。
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.Master ではなく Page のみを反復するようにしました。
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: ビルド キャッシュの問題のようです。James のコードが機能するようになりました。その後、動作しないように変更しました...それでも動作します。