正在会话对象中保存webControls

本文关键字:保存 webControls 对象 会话 | 更新日期: 2023-09-27 18:24:00

我有一个面板(pnlPanel),里面有很多控件,比如Textboxes and DropDownLists。当用户返回页面时,我希望它们是持久的,所以我尝试了这个:

/*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;
    }
}

但它不起作用。有可能吗?我之所以想这样做,是因为开销不是问题,而且我想减少编码时间。

正在会话对象中保存webControls

我自己从未尝试过,但在我看来,这是一个非常糟糕的主意。如果不进行测试,我猜这将产生大量ViewState问题。即使您可以维护ViewState,试图对多个页面加载保持这种控制充其量也是危险的。

我的建议是使用一个包含所需面板属性的公共对象,然后在早期事件中构建一个方法,用这些属性预填充新面板。

在不知道这样做的全部原因的情况下,您应该看看输出缓存指令。最好将内容从面板中取出并放入用户控件中。然后使用VaryByCustom在控件上设置输出缓存,这样您就可以使用用户名或其他一些唯一标识符按用户进行分隔。

http://msdn.microsoft.com/en-us/library/hdxfb6cy.aspx和http://msdn.microsoft.com/en-us/library/system.web.httpapplication.getvarybycustomstring.aspx

如果您在网络农场场景中,使用会话和/或缓存将是有问题的。缓存的作用域是应用程序实例,因此web场中的另一台服务器将无法访问它。

类似的其他一些副作用包括视图状态问题。

您在这里试图做的是缓存Panel,但这不是方法。保存时的面板是内存中正在运行的对象,无法按原样保存。您需要将其转换为html字符串并保存和缓存此字符串。因此,在面板附近放置一个文字,然后渲染面板并将其保存在会话中,然后实际显示此渲染中的文本。

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;

需要一些测试。我对自定义控件和自定义缓存使用了一些类似的代码,从不在会话中保存这么多数据。

第一种方法


protected void Page_Load(object sender, EventArgs e)
{       
    if (ViewState["panel"] != null)
    {
        panel = ViewState["panel"] as Panel;
    }
}

在这种方法中,ViewState对象是不同的。一旦ViewState["panel"]被赋予控制内存,并且对象被访问时,您可能会得到一些空值,以为会话是Session["panel"]


第二种方法


完整面板HTML保存在数据库中,并通过将函数保持在IsPostBack下,在表单加载上访问它。

现在使用方法-2的连续性,将值分配给会话对象。

this.Controls.Add(new LiteralControl("Your HTML"));

第三种方法


您可以使用文件系统。将div保存在文件中,并在运行时访问该文件。

希望这能对你有所帮助。


EDIT-1=>添加了第二种方法的代码

我也遇到了类似的问题。我试图将一个对象保存到存储面板的视图状态,但收到一条错误消息,告诉我面板不可序列化。您可以尝试使用SerializationSurrogate。https://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializationsurrogate(v=vs.110).aspx