Daarwin
Daarwin

Reputation: 3014

Saving webControls in the Session object

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

Answers (5)

Michael Kaldwid
Michael Kaldwid

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

Pankaj
Pankaj

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

Aristos
Aristos

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

Darthg8r
Darthg8r

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

Joel Etherton
Joel Etherton

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

Related Questions