簡體   English   中英

ASP.NET回發中的數據持久性

[英]Data Persistence across ASP.NET postbacks

語境:

我經常遇到這樣的情況:我們的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;
    }
}

人們經常試圖通過做這樣的事情來解決它:

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

但是,當兩個標簽已經加載並且用戶正在更改GridView值時,出於某種奇怪的原因,他試圖通過點擊另一頁上的“保存”按鈕來保存數據呢? 我個人不喜歡這個選項。

其他方法是將數據放在ViewState 但是,當涉及到持久存在的大型列表時,它可能會在頁面存儲在頁面上時嚴重影響頁面( HiddenField )。

但是,這項工作的最佳方式是什么? 有一次,我想與ViewState一起使用Session ,其中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;
    }
}

另一方面,每當用戶進入頁面時,它將向會話存儲新的數據列表。 哪會影響服務器內存。 也許他們可能會以某種方式被刪除。

題:

考慮到瀏覽器上多個選項卡的上下文,服務器和維護編碼團隊的成本較低,在Postbacks中保留這類數據的最佳方法是什么?

更新:

正如@nunespascal很好地發布,一個選項是使用SessionPageStatePersisterViewState存儲在Session 但不幸的是,這不是我的選擇。 然而,它與我上一個示例沒有太大區別,將數據保存在由ViewState上存儲的UniqueId索引的Session上。

還有其他選擇嗎?

這個問題有一個簡單的解決方案。 將ViewState存儲在會話中。

為此,您需要使用SessionPageStatePersister

參考: 頁面狀態持久性

您需要做的就是覆蓋PageStatePersister並使其使用SessionPageStatePersister而不是默認的HiddenFieldPageStatePersister

protected override PageStatePersister PageStatePersister
{
    get
    {
        return new SessionPageStatePersister(this);
    }
}

這甚至可以省去維護唯一密鑰的麻煩。 將自動使用隱藏字段來為每個頁面實例保留唯一鍵。

我遇到過類似的情況。 我們的想法是,如果您允許每個用戶使用長會話來更改網格視圖,這意味着您還會遇到並發問題,因為最終您只接受對數據進行的最后一組修改。

所以,我的解決方案是,允許更改數據庫,但確保所有用戶通過SignalR看到相同的狀態。

現在,並發問題已經消失,但您仍需要動態進行更改。 畢竟,您可能不想保存更改。 我已經通過應用命令設計模式解決了這個問題。 現在,任何一組更改都可以被批准或丟棄。 每當您檢查索引時,您將看到最后批准的gridview。 轉到更新頁面,您會看到實時更新的gridview。 此外,請修改以查看舊的已批准的gridview - 命令設計模式的其他優點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM