为什么我的 HiddenField 在第二次尝试实例化时失败?
Why does my HiddenField fail on a second attempt to instantiate?
在我的网页上,几乎所有元素(分为 panels/divs)都是在用户选择两个选项之一(显示这个或显示那个)后动态创建的。
不过,在提交表单后,表单 returns 恢复到其原始 pristne/austere 状态。因此,我必须像这样在代码隐藏的 Page_Load() 事件中重新创建这些片段:
if (Page.IsPostBack)
{
GenerateSection1();
GenerateSection2();
GenerateSection3();
GenerateSection4();
GenerateSection5();
}
但是,这在 GenerateSection1() 方法中失败,在最后一行显示如下:
boxDeptDivSection1 = new TextBox
{
CssClass = "finaff-webform-field-input",
ID = "deptdivtextbox_MailStopRow"
};
if (!(String.IsNullOrEmpty(userDepartment)))
{
boxDeptDivSection1.Text = userDepartment;
}
cellDeptDivTextbox.Controls.Add(boxDeptDivSection1);
dynamicTable.Rows.Add(row6);
HiddenField hfUserEmail = new HiddenField();
hfUserEmail.ID = "hfuseremail";
hfUserEmail.Value = usersEmail;
this.Controls.Add(hfUserEmail);
所以我可以添加 "normal" 类型的元素,但是尝试 [重新] 创建 HiddenField 会导致它爆炸:
System.Web.HttpException 未被用户代码处理
Message=加载视图状态失败。加载视图状态的控件树必须与上次请求期间用于保存视图状态的控件树相匹配。例如,当动态添加控件时,在 post-back 期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配。
来源=System.Web
错误代码=-2147467259
堆栈跟踪:
在 System.Web.UI.Control.LoadViewStateRecursive(对象保存状态)
在 System.Web.UI.Control.AddedControl(Control 控件, Int32 索引)
在 DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.GetSection1Table()
在 DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.GenerateSection1()
在 DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.Page_Load(对象发送者,EventArgs e)
在 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,对象 o,对象 t,EventArgs e)
在 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(对象发送者,EventArgs e)
在 System.Web.UI.Control.OnLoad(EventArgs e)
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Control.LoadRecursive()
在 System.Web.UI.Page.ProcessRequestMain(布尔 includeStagesBeforeAsyncPoint,布尔 includeStagesAfterAsyncPoint)
内部异常:
我该如何解决这个问题?
更新
也许问题出在元素 ID 的自动生成的前缀官网上,正如您在下面看到的,最初是“ctl00_ctl24_g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33_ctl00_hfuseremail”(甚至虽然我给它分配了一个沉默寡言的好ID "hfuseremail"
这些是 "View Source" 中对 "hfuseremail" 的唯一引用:
$(document).on("click", '[id$=rbPaymentForSelf]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideUp();
$('[id$=panelSection3]').slideUp();
hide_sections();
$('[id$=rbPaymentToIndividual]').attr('checked', true).click();
$('[id$=boxemailsection1]').val(function () {
return $('[id$=hfuseremail]').val();
})
}
});
$(document).on("click", '[id$=rbCampusAddress]', function () {
if (this.checked) {
$('[id$=_MailStopRow]').slideDown();
$('[id$=_AddressRows]').slideUp();
$('[id$=boxemailsection1]').val(function () {
return $('[id$=hfuseremail]').val();
})
}
});
<input type="hidden" name="ctl00$ctl24$g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33$ctl00$hfuseremail" id="ctl00_ctl24_g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33_ctl00_hfuseremail" value="platypus@ucsc.edu" />
更新 2
毕竟它可能与 HiddenField 无关;我深入研究了 Sharepoint 的 DOS 风格相关 ID 日志文件,发现:
System.Web.HttpException: 发现多个具有相同 ID 'pdfgenbtnclicked' 的控件。 FindControl 要求控件具有唯一 ID。
更新 3
这已经变成了一个真正的打地鼠问题,因为在添加代码以确保没有重新添加控件 (pdfgenbtnclicked') 之后,我得到:
...具有相同ID的多个控件'panelSection1'...
不管今天是不是海盗日,我说,"arrggghhhhhhhhhh!!!"
...和"Yo Ho Ho, and a bottle of Beer!"
更新 4
好的,我明白为什么 Sharepoint 不想重新创建与现有元素具有相同 ID 的元素(即使那些现有元素被隐藏)- 可以这么说,ID 是唯一键。那么,在有条件地动态创建元素,然后提交表单,将 form/page 反转回初始状态,并想再次显示这些元素之后,我有什么办法?他们不 exist/are 为空,但没有 "released" 他们的 ID 供重复使用。我知道元素不再存在,因为我首先尝试将它们设置为 "Visible":
panelSec1.Visible = true; // this is null (as are the rest)
. . .
...但是崩溃了,因为它们(panelSec1、panelSec2 等)为空。
此时我唯一能想到的就是给他们一个随机ID,比如这样:
panelSec1.ID = GetRandomVal() + "panelSection1";
...而不是现有的:
panelSec1.ID = "panelSection1";
想法?
还有其他事情发生(您是否阅读了错误消息)?我的猜测是您的代码中存在某种 if 条件,导致控件树在渲染与渲染之间略有不同,这会导致视图状态错误。
为什么要动态生成隐藏字段?把它放在页面上。反正都是隐藏的。如果你真的不希望它发出任何 HTML 你可以禁用它
问题似乎是 ID 被第二次重复使用了。
在我的网页上,几乎所有元素(分为 panels/divs)都是在用户选择两个选项之一(显示这个或显示那个)后动态创建的。
不过,在提交表单后,表单 returns 恢复到其原始 pristne/austere 状态。因此,我必须像这样在代码隐藏的 Page_Load() 事件中重新创建这些片段:
if (Page.IsPostBack)
{
GenerateSection1();
GenerateSection2();
GenerateSection3();
GenerateSection4();
GenerateSection5();
}
但是,这在 GenerateSection1() 方法中失败,在最后一行显示如下:
boxDeptDivSection1 = new TextBox
{
CssClass = "finaff-webform-field-input",
ID = "deptdivtextbox_MailStopRow"
};
if (!(String.IsNullOrEmpty(userDepartment)))
{
boxDeptDivSection1.Text = userDepartment;
}
cellDeptDivTextbox.Controls.Add(boxDeptDivSection1);
dynamicTable.Rows.Add(row6);
HiddenField hfUserEmail = new HiddenField();
hfUserEmail.ID = "hfuseremail";
hfUserEmail.Value = usersEmail;
this.Controls.Add(hfUserEmail);
所以我可以添加 "normal" 类型的元素,但是尝试 [重新] 创建 HiddenField 会导致它爆炸:
System.Web.HttpException 未被用户代码处理 Message=加载视图状态失败。加载视图状态的控件树必须与上次请求期间用于保存视图状态的控件树相匹配。例如,当动态添加控件时,在 post-back 期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配。 来源=System.Web 错误代码=-2147467259 堆栈跟踪: 在 System.Web.UI.Control.LoadViewStateRecursive(对象保存状态) 在 System.Web.UI.Control.AddedControl(Control 控件, Int32 索引) 在 DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.GetSection1Table() 在 DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.GenerateSection1() 在 DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.Page_Load(对象发送者,EventArgs e) 在 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,对象 o,对象 t,EventArgs e) 在 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(对象发送者,EventArgs e) 在 System.Web.UI.Control.OnLoad(EventArgs e) 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Page.ProcessRequestMain(布尔 includeStagesBeforeAsyncPoint,布尔 includeStagesAfterAsyncPoint) 内部异常:
我该如何解决这个问题?
更新
也许问题出在元素 ID 的自动生成的前缀官网上,正如您在下面看到的,最初是“ctl00_ctl24_g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33_ctl00_hfuseremail”(甚至虽然我给它分配了一个沉默寡言的好ID "hfuseremail"
这些是 "View Source" 中对 "hfuseremail" 的唯一引用:
$(document).on("click", '[id$=rbPaymentForSelf]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideUp();
$('[id$=panelSection3]').slideUp();
hide_sections();
$('[id$=rbPaymentToIndividual]').attr('checked', true).click();
$('[id$=boxemailsection1]').val(function () {
return $('[id$=hfuseremail]').val();
})
}
});
$(document).on("click", '[id$=rbCampusAddress]', function () {
if (this.checked) {
$('[id$=_MailStopRow]').slideDown();
$('[id$=_AddressRows]').slideUp();
$('[id$=boxemailsection1]').val(function () {
return $('[id$=hfuseremail]').val();
})
}
});
<input type="hidden" name="ctl00$ctl24$g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33$ctl00$hfuseremail" id="ctl00_ctl24_g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33_ctl00_hfuseremail" value="platypus@ucsc.edu" />
更新 2
毕竟它可能与 HiddenField 无关;我深入研究了 Sharepoint 的 DOS 风格相关 ID 日志文件,发现:
System.Web.HttpException: 发现多个具有相同 ID 'pdfgenbtnclicked' 的控件。 FindControl 要求控件具有唯一 ID。
更新 3
这已经变成了一个真正的打地鼠问题,因为在添加代码以确保没有重新添加控件 (pdfgenbtnclicked') 之后,我得到:
...具有相同ID的多个控件'panelSection1'...
不管今天是不是海盗日,我说,"arrggghhhhhhhhhh!!!"
...和"Yo Ho Ho, and a bottle of Beer!"
更新 4
好的,我明白为什么 Sharepoint 不想重新创建与现有元素具有相同 ID 的元素(即使那些现有元素被隐藏)- 可以这么说,ID 是唯一键。那么,在有条件地动态创建元素,然后提交表单,将 form/page 反转回初始状态,并想再次显示这些元素之后,我有什么办法?他们不 exist/are 为空,但没有 "released" 他们的 ID 供重复使用。我知道元素不再存在,因为我首先尝试将它们设置为 "Visible":
panelSec1.Visible = true; // this is null (as are the rest)
. . .
...但是崩溃了,因为它们(panelSec1、panelSec2 等)为空。
此时我唯一能想到的就是给他们一个随机ID,比如这样:
panelSec1.ID = GetRandomVal() + "panelSection1";
...而不是现有的:
panelSec1.ID = "panelSection1";
想法?
还有其他事情发生(您是否阅读了错误消息)?我的猜测是您的代码中存在某种 if 条件,导致控件树在渲染与渲染之间略有不同,这会导致视图状态错误。
为什么要动态生成隐藏字段?把它放在页面上。反正都是隐藏的。如果你真的不希望它发出任何 HTML 你可以禁用它
问题似乎是 ID 被第二次重复使用了。