Reputation: 3014
I have a panel (pnlPanel) with lots of controls like Textboxes and DropDownLists
. I want them to be persistent when the user gets back to the page, so i tried this:
/*i have saved the panel like this
Session["testPanel"] = pnlTest;
*/
protected void Page_Load(object sender, EventArgs e)
{
if (Session["testPanel"] != null)
{
panel = Session["testPanel"] as Panel;
}
}
But its not working. Is it possible? The reason why i want to do this is because overhead is not a problem, and i want to cut down on coding time.
Upvotes: 0
Views: 2673
Reputation: 72
I had a similar problem. I tried to save an object to the View State that stored a Panel and I got an error message telling me that Panels aren't serializable. You could try using a SerializationSurrogate. https://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializationsurrogate(v=vs.110).aspx
Upvotes: 0
Reputation: 10105
First Approach
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["panel"] != null)
{
panel = ViewState["panel"] as Panel;
}
}
In this approach your ViewState objects were different. You may be getting some null values once the ViewState["panel"]
is given the control memory and the object is being accessed in the impression that the Session was Session["panel"]
Second Approach
Save the Complete panel HTML in database and access it on the form load by keeping the function under IsPostBack
.
Now with the continuity of approach - 2 assign the value to your session object.
this.Controls.Add(new LiteralControl("Your HTML"));
Third Approach
You can use File system. Save the div in your file and access the file at runtime.
Hope this may help you.
EDIT - 1 => Added code for second approach
Upvotes: 0
Reputation: 66641
What you try to do here is to cache the Panel but this is not the way. The panel as you save it is a running object on the memory and can not be saved as it is. You need to convert it to html string and save and cache this string. So near the Panel you place a literal, then you render the Panel and save it on session, and then actually you display the text from this render.
if(Session["testPanel"] == null)
{
TextWriter stringWriter = new StringWriter();
HtmlTextWriter renderOnMe = new HtmlTextWriter(stringWriter);
// render and get the actually html of this dom tree
testPanel.RenderControl(renderOnMe);
// save it as cache
Session["testPanel"] = stringWriter.ToString();
}
// render the result on a literal
cLiteralID.Text = Session["testPanel"];
// hide the panel because I have render it on literal.
testPanel.Visible = false;
Need some tests as is it. I use some similar code for custom control and custom cache, never save on session this amount of data.
Upvotes: 0
Reputation: 12675
Without knowing the entire reason for doing something like this, you should have a look at output caching directives. You would be best served by pulling the content out of the panel and into a user control. Then setting output caching on control, using VaryByCustom so you can use the user name or some other unique identifier to separate by user.
http://msdn.microsoft.com/en-us/library/hdxfb6cy.aspx and http://msdn.microsoft.com/en-us/library/system.web.httpapplication.getvarybycustomstring.aspx
Using session and/or caching will be problematic if you are in a webfarm scenario. Cache is scoped to the application instance, so another server in the web farm will not have access to it.
Some other side effects of something like this include issues with viewstate.
Upvotes: 0
Reputation: 37533
I've never tried this myself, but this seems to me to be an extra-ordinarily bad idea. Without testing it, my guess would be that this will create a ton of ViewState problems. Even if you could maintain the ViewState, attempting to keep this control over multiple page loads would be dangerous at best.
My recommendation would be to have a common object that holds the properties of the panel you want and just build a method into one of the early events to prepopulate a new panel with those properties.
Upvotes: 1