在ASP.NET视图状态下存储字典<string,string =“”>?</string,>

时间:2011-06-09 17:47:51

标签: c# asp.net viewstate

我正在尝试将Dictionary<string, string>存储在我正在为ASP.NET 2.0开发的自定义控件的ViewState中:

private Dictionary<String, String> Items
    {
        get
        {
            object d = ViewState["Items"];
            return (d == null ? null : (Dictionary<String, String>)d);
        }
        set
        {
            ViewState["Items"] = value;
        }
    }

访问它看起来像这样:

public void UpdateData
{
    if (this.Items == null)
        this.Items = new Dictionary<string, string>();
    else
        this.Items.Clear();
    //Fill the collection
}

当第一次加载页面时设置它,它似乎工作正常。但是在随后的回发中,返回的值始终为null(第一个条件总是发生)。调试显示它已从属性null中的ViewState中获取get

我已完成一些研究并且found类必须实现IStateManager才能在ViewState中保存,而Dictionary MSDN page似乎表示Dictionary<TKey, TValue>没有。但我之前在ViewState中存储了字典没有问题。这里发生了什么?我以前的经历是侥幸吗?

更新:我尝试在属性中添加一些测试代码:ViewState["ItemTest"] = "foo";中的setstring test = (string)ViewState["ItemTest"];中的get。就像Dictionary一样,它出来了。因此,Dictionary可序列化似乎不是问题。另外,为了澄清,UpdateData是从我的RenderControl覆盖中调用的,它发生在包含控件的页面中的Page_Load之后。

2 个答案:

答案 0 :(得分:8)

您可以将字典存储在ViewState中,但是您在页面生命周期中尝试执行此操作的时间太晚。就像在Init之后加载ViewState一样,ViewState在控件呈现之前保存。将您的逻辑移出RenderControl并进入生命周期早期的另一个方法或事件处理程序,例如PreRender

protected override void OnPreRender(EventArgs e)
{
    if (this.Items == null)
    {
        this.Items = new Dictionary<string, string>();
    }

    base.OnPreRender(e);
}

只要未在控件或其父控件上禁用ViewState,您就会注意到该对象在后续回发中不再为空。

答案 1 :(得分:1)

请确保您未在​​页面生命周期中过早访问该属性,因为未直接加载视图状态。

首次请求此属性的方法(页面生命周期中的哪一点)?