C# 在会话对象中保存网络控件

C# 在会话对象中保存网络控件,c#,asp.net,session,C#,Asp.net,Session,我有一个面板(pnlPanel),上面有很多控件,比如文本框和下拉列表。我希望它们在用户返回页面时保持持久性,因此我尝试了以下方法: /*i have saved the panel like this Session["testPanel"] = pnlTest; */ protected void Page_Load(object sender, EventArgs e) { if (Session["testPanel"] != null) {

我有一个面板(pnlPanel),上面有很多控件,比如
文本框和下拉列表。我希望它们在用户返回页面时保持持久性,因此我尝试了以下方法:

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

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

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

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


这类操作的其他一些副作用包括viewstate的问题。

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


我的建议是使用一个公共对象来保存所需面板的属性,只需将一个方法构建到其中一个早期事件中,即可使用这些属性预填充新面板。

第一种方法


在这种方法中,ViewState对象是不同的。一旦
ViewState[“panel”]
被赋予控制内存,并且在会话是
Session[“panel”]


第二种方法


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

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

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

第三种方法


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

希望这能对你有所帮助



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

您在这里尝试的是缓存面板,但这不是方法。保存时的面板是内存中正在运行的对象,无法按原样保存。您需要将其转换为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;

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

我也遇到过类似的问题。我试图将对象保存到存储面板的视图状态,但收到一条错误消息,告诉我面板不可序列化。您可以尝试使用序列化代理。

您是否尝试过
panel=(panel)会话[“testPanel”]是吗?此外,您的表达式表示“代码>会话[面板] 这会导致错误。您可能需要考虑ASP.NET用户控件缓存。如果将面板代码移动到用户控件中,则可以轻松缓存渲染的内容。面板包含文本框和下拉列表。它不工作。即时消息:在程序集System.Web中键入'System.Web.UI.WebControls.Panel',Version=2.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a'未标记为可序列化。受保护的无效页面加载(对象发送方,事件参数e){if(ViewState[“testPanel”!=null){pnlTest=(Panel)ViewState[“testPanel”]}受保护的无效按钮单击(对象发送者,事件参数e){ViewState[“testPanel”]=pnlTest;label.Text=“Saved:”+ViewState[“testPanel”].ToString()}this.Controls.Add(新的文本控件(“您的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;