あなたの無限の知識がこの問題の解決に役立つことを願っています。答えを得るのに十分なほど類似した質問が見つかりませんでした。
コードが tl;dr の場合、またはその逆の場合の概要
一連のユーザー コントロールがあり、それぞれが入力フォームであり、送信されると電子メールが生成され、関連する場所に内部的に送信されます。すべてのフォームは同じページに表示され、次のように構成されています。
updatepanel があります。updatepanel 内にはマルチビューがあり、ビューの 1 つにすべての電子メール フォームのユーザー コントロールがあります。このコントロールである EmailForms.ascx は、基本的に 1 行 2 セルのテーブルで、左側のセルにツリービューがあり、右側のセルにプレースホルダーがあります。ツリービューの各リーフ ノードの値は、プレースホルダーに読み込まれる子メール フォーム ユーザー コントロールの URL を保持します。コントロールが読み込まれると、URL はセッション状態に保存されPage_Init
、子メール フォームがポストバックする必要がある場合に再読み込みされます。
個々のメール フォームにはそれぞれ独自の送信ボタンがありScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(btn_Submit)
、関数で呼び出されPage_Init
ます。フォームにポストバックを発生させる必要がある他の要素がある場合、それらはこの方法で登録されます。
問題すべてがほぼ完全に機能します-私の問題は、具体的には、表示される子メールフォームを変更した後
の最初のポストバックです。ユーザーがフォームに入力して送信すると、すべての入力領域がクリアされ、すべてのバリデータが false として表示され、電子メールは生成されません。その後のすべてのポストバックは、子メール フォームを別のフォームに再度変更するまで、正常に機能します。最初に読み込まれる電子メール フォームでは、この問題は発生しません。
この動作の原因と、それを防ぐ方法を誰かが提案できますか? これは、以前に読み込まれたフォームのビューステートにあった値を送信しようとしている可能性がありますか?
デフォルト.aspx
<body>
<form id="MainForm" runat="server">
<asp:ScriptManager ID="NavigatorScriptManager" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>
<!-- irrelevant stuff omitted -->
<asp:UpdatePanel ID="upd_Pan1" runat="server" >
<ContentTemplate>
<asp:MultiView ID="multi_MainRealContent" runat="server" ActiveViewIndex="0" >
<!-- Other views are fine -->
<asp:View runat="server" ID="View4">
<asp:Panel runat="server" ID="Panel5" CssClass="ViewContainer LeftAlignment">
<UsrCtrl:EmailForms ID="Sp_Emails" runat="server" width="95%" />
</asp:Panel>
</asp:View>
</asp:MultiView>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
メールフォーム.ascx
<asp:Table runat="server" ID="tbl_ToolSelect" Width="100%" CellSpacing="0" CssClass="LayoutTable EmailFormsTable">
<asp:TableRow ID="TableRow1" runat="server">
<asp:TableCell ID="TableCell1" runat="server" Width="300px">
<asp:TreeView runat="server" ID="tree_EmailForms"
DataSourceID="xml_EmailForms"
ExpandDepth="0" ShowLines="false"
NodeIndent="10" NodeWrap="True" PopulateNodesFromClient="false"
ShowExpandCollapse="True" >
<DataBindings>
<asp:TreeNodeBinding DataMember="Pillar" TextField="id" SelectAction="None" PopulateOnDemand="False" />
<asp:TreeNodeBinding DataMember="Group" TextField="id" SelectAction="None" PopulateOnDemand="False" />
<asp:TreeNodeBinding DataMember="Form" TextField="id" ValueField="url" SelectAction="Select" PopulateOnDemand="False" />
</DataBindings>
</asp:TreeView>
</asp:TableCell>
<asp:TableCell ID="TableCell2" runat="server" >
<asp:PlaceHolder runat="server" ID="Ctrl_Placeholder"></asp:PlaceHolder>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<asp:XmlDataSource ID="xml_EmailForms" runat="server" DataFile="EmailFormHeirarchy.xml" XPath="ROOT/*"></asp:XmlDataSource>
メールフォーム.ascx.vb
Protected Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
If (Not Session Is Nothing) AndAlso (Not Session("LastControl") Is Nothing) Then 'ONLY if we have selected an email form previously
'reload the UserControl
Dim ctrl As UserControl = LoadControl(Session("LastControl"))
Ctrl_Placeholder.Controls.Add(ctrl)
End If
End Sub
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(tree_EmailForms)
Page.ClientScript.RegisterClientScriptBlock(Me.GetType, "EmailFormsCSS", "<link href='EmailForms/EmailForms.css' rel='stylesheet' type='text/css' />")
End Sub
Protected Sub tree_EmailForms_SelectedNodeChanged(sender As Object, e As System.EventArgs) Handles tree_EmailForms.SelectedNodeChanged
Try
Ctrl_Placeholder.Controls.Clear()
Dim ctrl As UserControl = LoadControl(tree_EmailForms.SelectedNode.Value)
Ctrl_Placeholder.Controls.Add(ctrl)
Session("LastControl") = tree_EmailForms.SelectedNode.Value
Catch ex As System.Exception
//Occasional viewstate errors if there has been a long time between postbacks
SharedFunctions.LogError(Me.Page, ex.Message, ex.StackTrace)
End Try
End Sub
GenericChildEmailForm.ascx
<div class="descriptionArea">
<h2 class="centered">FORM HEADING</h2>
<p>FORM DESCRIPTION</p>
</div>
<div runat="server" id="inputArea" class="inputArea">
<asp:Table ID="inputTable" runat="server" CssClass="inputTable">
<asp:TableRow>
<asp:TableHeaderCell CssClass="LeftColumn">
<asp:Label runat="server" Text="FIELD HEADING"></asp:Label>
<asp:RequiredFieldValidator runat="server" ID="val_req_ID" ControlToValidate="ID" Display="Dynamic" EnableClientScript="true" ErrorMessage="MESSAGE"> *</asp:RequiredFieldValidator>
</asp:TableHeaderCell>
<asp:TableCell CssClass="RightColumn">
<asp:Textbox runat="server" id="ID" width="98%"></asp:textbox>
</asp:TableCell>
</asp:TableRow>
<!-- repeat the above table row as required -->
<asp:TableRow>
<asp:TableCell ID="cell_HR" ColumnSpan="2">
<div style="width:98%"><hr /></div>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell ID="cell_Submit" ColumnSpan="2">
<asp:Button runat="server" ID="btn_Submit" Text="Submit" Width="98%" Height="30px" CausesValidation="true" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</div>
<div runat="server" id="errorArea" class="errorArea">
<asp:ValidationSummary runat="server" ID="val_Sumamry" DisplayMode="BulletList" ShowMessageBox="true" ShowSummary="false" />
</div>
<div runat="server" id="outputArea" class="confirmationArea">
</div>
GenericChildEmailForm.ascx.vb
Protected Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(btn_Submit)
End Sub
Protected Sub btn_Submit_Click(sender As Object, e As System.EventArgs) Handles btn_Submit.Click
//this function iterates over the input table and extracts the value fields of whatever controls appear in the cells. <hr> and submit rows excluded.
Dim emailBody As String = SharedFunctions.PrepareEmailBody(inputTable, Me.Page)
SharedFunctions.Send_Email("toAddress", "fromAddress", "displayName", "subject", emailBody)
outputArea.InnerHtml = "<h3>Email Sent</h3><p>A copy for your notes...</p><hr />" & emailBody
LogUsage() //in local database
SharedFunctions.ClearForm(FindControl("inputArea"))
End Sub