0

そのため、フォームにユーザーが入力する複数のコントロール (テキスト ボックス、ドロップダウン、ラジオ ボタンなど) がある場合に、このコードをしばらく使用してきました。 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 のコードが機能するようになりました。その後、動作しないように変更しました...それでも動作します。

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 に答える