我在页面中有一个自定义控件,它使用完全和部分输出缓存。如果我只是刷新页面,则从缓存加载控件(我已经添加了一个时间戳来验证)。但是如果我在导致PostBack的控件中执行操作,那么我第二次执行它时ViewState"失去" !IsPostBack
时在Page_Load中添加的值。我想知道是否有某种方法可以让ViewState和OutputCache以这种方式工作。
public partial class MyUserControl : MyBaseUserControl
{
private string MyProperty
{
get { return (string)ViewState["_myProperty"]; }
set { ViewState["_myProperty"] = value; }
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
var prop = this.MyProperty;
}
protected void Page_Load(object sender, EventArgs e)
{
// Do something
if (IsPostBack)
{
var value = this.MyProperty; // sometimes gets null
}
else
{
this.MyProperty = GetNewValue(); // never returns empty or null
}
}
}
修改:在发布问题后,SO显示了其他相关问题(例如this),因此我查看了页面生命周期并覆盖了LoadViewState
方法,并设置断点。首次加载页面(和控件)时,会调用Page_Load
,但不会调用LoadViewState
;在第一个PostBack中,LoadViewState
被调用,MyProperty
具有正确的内容;在第二个PostBack中,再次调用Page_Load
,但LoadViewState
没有,MyProperty
有null
值。
编辑2 我已经调试了一点(通过比较执行与禁用输出缓存)并发现控件回发(asp:GridView
' s { {1}} event)通过在页面中注入OnSelectedIndexChanging
JavaScript来强制刷新页面。但是启用缓存后,gridview的事件仅在第一个回发中执行,而不在第二个回发中执行,从而阻止重新加载页面(以及随后的控件)以完成其任务。但它不是唯一的问题,因为ViewState中存储了属性。