ASP.NET回发中的数据持久性

Mt.*_*ers 13 c# asp.net viewstate session webforms

语境:

我经常遇到这样的情况:我们的ASP.NET页面必须在GridView上向用户显示数据,让他随心所欲地更改它(单元格上的文本框),并且只有当他实际点击时才将其保存到数据库中.保存按钮".此数据通常是页面上信息的虚拟状态,这意味着用户可以更改所有内容,而无需保存,直到他点击"保存按钮".在这些情况下,总是需要在ASP.NET回发中保留数据列表.这些数据可以是一个DataTable或只是一些的实例List<Someclass>.

我经常看到人们实现这一点并持久保存数据Session.在这种情况下,我通常也会看到一些用户导航时打开多个标签的问题,有些时候在同一页面上.两个不同选项卡的数据将合并在一起,导致信息被扰乱的问题.

如何经常使用Session的示例:

private List<SomeClass> DataList
{
    get
    {
        return Session["SomeKey"] as List<SomeClass>;
    }
    set 
    {
        Session["SomeKey"] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

人们经常试图通过做这样的事情来解决它:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataList = null
    }
    else
    {
        FillGridView(DataList);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当两个标签已经加载并且用户正在更改GridView值时,出于某种奇怪的原因,他试图通过点击另一页上的"保存"按钮来保存数据呢?我个人不喜欢这个选项.

其他方法是将数据放在上面ViewState.但是,当涉及到持久存在的大型列表时,它可能会在页面存储时严重影响页面(HiddenField).

但是,这项工作的最佳方式是什么?有一次,我想SessionViewState在哪里一起使用ViewState将保存一个唯一的标识符来索引Session保存的数据.这样可以防止在浏览器上的标签之间共享数据:

private List<SomeClass> DataList
{
    get
    {
        if (ViewState["SomeKey"] == null)
        {
            ViewState["SomeKey"] = Guid.NewGuid().ToString();
        }

        return Session[ViewState["SomeKey"].ToString()] as List<SomeClass>;
    }
    set {

        if (ViewState["SomeKey"] == null)
        {
            ViewState["SomeKey"] = Guid.NewGuid().ToString();
        }

        Session[ViewState["SomeKey"].ToString()] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

另一方面,每当用户进入页面时,它将向会话存储新的数据列表.哪会影响服务器内存.也许他们可能会以某种方式被删除.

题:

考虑到浏览器上多个选项卡的上下文,服务器和维护编码团队的成本较低,在Postbacks中保留这类数据的最佳方法是什么?

更新:

正如@nunespascal很好地发布,一个选项是存储ViewStateSession使用中SessionPageStatePersister.但不幸的是,这不是我的选择.然而,它与我上一个示例没有太大区别,将数据保存在由ViewState上存储的UniqueId索引的Session上.

还有其他选择吗?

nun*_*cal 2

这个问题有一个简单的解决方案。将 ViewState 存储在 Session 中。

为此,您需要使用SessionPageStatePersister

参考:页面状态持久化

您需要做的就是覆盖PageStatePersister并使用它SessionPageStatePersister而不是默认值HiddenFieldPageStatePersister

protected override PageStatePersister PageStatePersister
{
    get
    {
        return new SessionPageStatePersister(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

这甚至可以让您免去维护唯一密钥的麻烦。将自动使用隐藏字段来为页面的每个实例保留唯一的键。