同じページに複数の ModalPopupExtenders があり、それぞれに検証が必要であるという問題。なんらかの理由で、2 回目の検証が開始されますが (つまり、エラー メッセージが表示されます)、ポストバックはキャンセルされず、コード ビハインドで Page.IsValid が true になっています。最初の MPE では、ポストバックがキャンセルされ、コード ビハインドにヒットすることはありません。
モーダルのマークアップ:
<asp:Panel ID="pnlIndicatorEdit" runat="server" CssClass="modalPopup" style="display: none; width: 400px;">
<h3>Indicator edit</h3>
Name: <asp:TextBox ID="txtName" runat="server" Width="200px" />
<asp:RequiredFieldValidator ID="rfvIndicatorName" runat="server" Display="Dynamic" ControlToValidate="txtName"
ErrorMessage="Required" ValidationGroup="Indicator" CssClass="validator" />
<br />
Active:
<asp:RadioButtonList ID="rblActive" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow">
<asp:ListItem Text="True" Value="True" />
<asp:ListItem Text="False" Value="False" />
</asp:RadioButtonList>
<br />
Category: <asp:DropDownList id="ddlCategory" runat="server" DataTextField="Name" DataValueField="KpiCategoryId" />
<br />
Indicator Type: <asp:DropDownList id="ddlIndicatorType" runat="server" DataTextField="Name" DataValueField="IndicatorTypeId" />
<br />
Inspection Item: <asp:DropDownList ID="ddlInspectionItem" runat="server" DataTextField="FriendlyName"
DataValueField="InspectionItemId" AppendDataBoundItems="true">
<asp:ListItem Text="--None--" Value="" />
</asp:DropDownList>
<br />
Instructions: <asp:TextBox ID="txtInstructions" runat="server" TextMode="MultiLine" Columns="40" Rows="5" />
<br /><br />
<asp:Button ID="btnIndicatorSave" runat="server" CssClass="button-save" Text="Save" OnClick="btnIndicatorSave_Click" ValidationGroup="Indicator" /> <asp:Button ID="btnCancel" runat="server" CssClass="button-cancel" Text="Cancel" runat="server" CausesValidation="false" />
</asp:Panel>
<asp:Panel ID="pnlTargetEdit" runat="server" CssClass="modalPopup" style="display: none; width: 400px;">
<h3>Target edit</h3>
Indicator: <asp:Label ID="lblTargetIndicator" runat="server"/> Program: <asp:Label ID="lblTargetProgram" runat="server" />
<br />
<asp:RadioButtonList ID="rblTargetActive" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow">
<asp:ListItem Text="True" Value="True" />
<asp:ListItem Text="False" Value="False" />
</asp:RadioButtonList>
<br />
Value: <asp:TextBox ID="txtTargetValue" runat="server" ValidationGroup="target" />
<asp:RequiredFieldValidator ID="rfvTargetValue" runat="server" ControlToValidate="txtTargetValue"
ErrorMessage="Value is required" CssClass="validator" Display="Dynamic" Text="Required" />
<br />
<asp:Button ID="btnTargetSave" runat="server" CssClass="button-save" Text="Save" OnClick="btnTargetSave_Click" ValidationGroup="target" /> <asp:Button ID="btnTargetCancel" runat="server" CssClass="button-cancel" Text="Cancel" runat="server" CausesValidation="false" />
</asp:Panel>
<asp:HyperLink ID="lnkHiddenIndicatorEdit" style="display:none;" runat="server" />
<ajaxToolkit:ModalPopupExtender ID="mpeIndicatorEdit" BehaviorID="mpeIndicatorEdit" runat="server" TargetControlID="lnkHiddenIndicatorEdit"
PopupControlID="pnlIndicatorEdit" CancelControlID="btnCancel" BackgroundCssClass="modalBackground" />
<asp:HyperLink ID="lnkHIddenTargetEdit" style="display:none;" runat="server" />
<ajaxToolkit:ModalPopupExtender ID="mpeTargetEdit" BehaviorID="mpeTargetEdit" runat="server" TargetControlID="lnkHiddenTargetEdit"
PopupControlID="pnlTargetEdit" CancelControlID="btnTargetCancel" BackgroundCssClass="modalBackground" />
サーバー側コード:
protected void btnIndicatorSave_Click(object sender, EventArgs e)
{
//Never hit if vaildation fires
try
{
Indicator indicator = IndicatorFactory.GetById(IndicatorId);
indicator.Name = txtName.Text;
int newCategoryId = 0;
Int32.TryParse(ddlCategory.SelectedValue, out newCategoryId);
if (indicator.Category.KpiCategoryId != newCategoryId)
{
indicator.Category = KpiCategoryFactory.GetById(newCategoryId);
}
int newIndicatorTypeId = 0;
Int32.TryParse(ddlIndicatorType.SelectedValue, out newIndicatorTypeId);
if (indicator.IndicatorType.IndicatorTypeId != newIndicatorTypeId)
{
indicator.IndicatorType = IndicatorTypeFactory.GetById(newIndicatorTypeId);
}
indicator.IsActive = bool.Parse(rblActive.SelectedValue);
indicator.Instructions = txtInstructions.Text;
int newInspectionItemId = 0;
Int32.TryParse(ddlInspectionItem.SelectedValue, out newInspectionItemId);
if (indicator.InspectionItem == null)
{
if (newInspectionItemId > 0)
{
indicator.InspectionItem = InspectionFactory.GetById(newInspectionItemId);
}
}
else
{
if (newInspectionItemId == 0)
{
indicator.InspectionItem = null;
}
else if (newInspectionItemId != indicator.InspectionItem.InspectionItemId)
{
indicator.InspectionItem = InspectionFactory.GetById(newInspectionItemId);
}
}
IndicatorFactory.Save(indicator);
DataBind();
divMsg.Visible = true;
lblMsg.Text = "Save Successful!";
}
catch (Exception ex)
{
Logger.Error("An error occurred trying to save indicator with id " + IndicatorId.ToString(), ex);
divMsg.Visible = true;
lblMsg.Text = "An error occurred trying to save the indicator";
}
finally
{
mpeIndicatorEdit.Hide();
}
}
protected void btnTargetSave_Click(object sender, EventArgs e)
{
//hit regardless of validation, IsValid = true
if (Page.IsValid)
{
try
{
//trying to get validation right before filling in update code.
}
catch (Exception ex)
{
Logger.Error("An error occurred trying to save target with id " + hdnTargetId.Value, ex);
divMsg.Visible = true;
lblMsg.Text = "An error occurred trying to save the target";
}
finally
{
mpeTargetEdit.Hide();
}
}
}