问题
On my web page, almost all the elements (which are divided into panels/divs) are created dynamically only after the user selects one of two choices (show this or show that).
After a form submission, though, the form returns to its original pristne/austere state. And so, I have to recreated those pieces, like so, in the code-behind's Page_Load() event:
if (Page.IsPostBack)
{
GenerateSection1();
GenerateSection2();
GenerateSection3();
GenerateSection4();
GenerateSection5();
}
However, this fails within the GenerateSection1() method, on the last line shown below:
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);
So I can add the "normal" types of elements, but trying to [re]create the HiddenField causes it to blow up with:
System.Web.HttpException was unhandled by user code Message=Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request. Source=System.Web ErrorCode=-2147467259 StackTrace: at System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at System.Web.UI.Control.AddedControl(Control control, Int32 index) at DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.GetSection1Table() at DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.GenerateSection1() at DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.Page_Load(Object sender, EventArgs e) at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) InnerException:
How can I get around this?
UPDATE
Perhaps the problem is with the automatically-generated prepended gobbledygook to the element's ID which, as you can see below, is at first "ctl00_ctl24_g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33_ctl00_hfuseremail" (even though I assign it a taciturnedly terrific ID of "hfuseremail"
These are the only references to "hfuseremail" in the "View Source":
$(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" />
UPDATE 2
It may be unrelated to the HiddenField, after all; I drilled down into the grimy bowels of Sharepoint's DOS-esque correlation ID log file, and found:
System.Web.HttpException: Multiple controls with the same ID 'pdfgenbtnclicked' were found. FindControl requires that controls have unique IDs.
UPDATE 3
And this has turned into a real whack-a-mole problem, because after adding code to make sure that control (pdfgenbtnclicked') isn't re-added, I get:
...Multiple controls with the same ID 'panelSection1'...
Whether it's talk-like-a-pirate-day or not, I say, "arrggghhhhhhhhhh!!!"
...and "Yo Ho Ho, and a bottle of Beer!"
UPDATE 4
Okay, I get why Sharepoint doesn't want to re-create elements with the same IDs as existing elements (even though those existing ones are hidden) - the IDs are unique keys, so to speak. So, what is my recourse after conditionally dynamically creating elements, then submitting the form, which revers the form/page back to the initial state, and wanting to show those elements again? They don't exist/are null, but have not "released" their IDs for re-use. I know that the elements no longer exist, because I first tried to set them to "Visible":
panelSec1.Visible = true; // this is null (as are the rest)
. . .
...but that crashed, as they (panelSec1, panelSec2, etc.) were null.
The only thing I can think of at this point is to give them a randomized ID, such as this:
panelSec1.ID = GetRandomVal() + "panelSection1";
...instead of the existing:
panelSec1.ID = "panelSection1";
Thoughts?
回答1:
There is something else going on (did you read the error message)? My guess is that there is some sort of if condition in your code that causes the control tree to be slightly different from render to render, and this is causing a viewstate error.
Why generate the hidden field dynamically? Just put it on the page. It's hidden anyway. If you really don't want it to emit any HTML you can disable it
回答2:
It seems the ID being re-used a second time was the problem.
来源:https://stackoverflow.com/questions/31545614/why-does-my-hiddenfield-fail-on-a-second-attempt-to-instantiate