2011-12-02 61 views
8

權,我有一件很奇特的事情在這裏......ViewState是上回發空

ASP.NET 4頁具有以下屬性:

protected QuickShopBag QuickShopBagInstance 
{ 
    get { return (QuickShopBag)ViewState["QuickShopBag"]; } 
    set { ViewState["QuickShopBag"] = value; } 
} 

在最初的Page_Load()在(!Page.IsPostBack)中填充QuickShopBagInstance並保存ViewState。

但是,當您在頁面上執行回發時,從回發Button_OnClick()事件中訪問時,ViewState爲空!

我已經檢查了Request.Form,並且確定_Viewstate的值已經存在並且已被填充。我也通過解析器運行了這個值,它確實包含了預期的數據,頁面有ViewStateEnabled =「true」和新的.NET 4 ViewStateMode =「Enabled」。

我已經開始重寫LoadViewState方法來檢查它是否正在觸發,它似乎不是。

protected override void LoadViewState(object savedState) 
{ 
    base.LoadViewState(savedState); 
} 

我真的失去了什麼可能是問題。有任何想法嗎?

+0

您不顯示您用於填充將內容放入視圖狀態的屬性的邏輯。 Probabily它在回發期間做了錯誤 –

+1

只需假設this.QuickShopBagInstance =新的QuickShopBag()在初始加載。我也已經說過,我已經驗證了正在傳回的視圖狀態數據,這是正確的。 –

+0

您可以請發佈QuickShopBag類定義。不需要這些屬性。 – Asken

回答

9

首先,有問題的代碼是不是在Page_Load中,但在Page_Init一個更好的解釋,雖然我沒有讀什麼,說你可以」在Init處分配給ViewState。

所以我放在一起復制我有問題的一個非常基本的測試...

<form id="form1" runat="server"> 
<div> 
    <asp:ListView id="QuickshopListView" runat="server"> 
     <LayoutTemplate> 
      <asp:PlaceHolder ID="itemPlaceHolder" runat="server" /> 
     </LayoutTemplate> 
     <ItemTemplate> 
      <asp:TextBox ID="txtItem" runat="server" Text='<%# Container.DataItem %>' /> 
      <asp:Button ID="btnDelete" runat="server" Text="Delete" OnClick="btnDelete_Click" /> 
      <br /> 
     </ItemTemplate> 
    </asp:ListView> 
    <asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click" /> 
</div> 
</form> 

public partial class Quickshop : System.Web.UI.Page 
{ 
    protected QuickShopBag QuickShopBagInstance 
    { 
     get { return (QuickShopBag)ViewState["QuickShopBag"]; } 
     set { ViewState["QuickShopBag"] = value; } 
    } 

    protected void Page_Init(object sender, EventArgs e) 
    { 
     if (!Page.IsPostBack) 
     { 
      if (QuickShopBagInstance == null) 
       QuickShopBagInstance = new QuickShopBag(); 

      if (!String.IsNullOrEmpty(Request.QueryString.ToString())) 
      { 
       string[] items = Server.UrlDecode(Request.QueryString.ToString()).Split(','); 
       if (items.Length > 0) 
       { 
        foreach (string item in items) 
        { 
         QuickShopBagInstance.QuickShopItems.Add(item); 
        } 
       } 
      } 
     } 
    } 

    protected void Page_LoadComplete(object sender, EventArgs e) 
    { 
     QuickshopListView.DataSource = QuickShopBagInstance.QuickShopItems; 
     QuickshopListView.DataBind(); 
    } 

    protected void btnAdd_Click(object sender, EventArgs e) 
    { 
     if (QuickShopBagInstance == null) 
      QuickShopBagInstance = new QuickShopBag(); 

     QuickShopBagInstance.QuickShopItems.Add("add1"); 
     QuickShopBagInstance.QuickShopItems.Add("add2"); 
     QuickShopBagInstance.QuickShopItems.Add("add3"); 
    } 

    protected void btnDelete_Click(object sender, EventArgs e) 
    { 
     Button DeleteButton = (Button)sender; 
     ListViewDataItem item = (ListViewDataItem)DeleteButton.NamingContainer; 
     QuickShopBagInstance.QuickShopItems.RemoveAt(item.DisplayIndex); 
    } 
} 

[Serializable] 
public class QuickShopBag 
{ 
    public List<string> QuickShopItems { get; set; } 

    public QuickShopBag() 
    { 
     this.QuickShopItems = new List<string>(); 
    } 
} 

如果請求說「/quickshop.aspx?add1,add2,add3」,ListView控件是正確填充來自qs的數據,但是當涉及到單擊刪除按鈕時,由於ViewState未持久存儲QuickShopBag對象,因此引發了NullReferenceException。

但是,如果您單擊「添加」按鈕,您可以看到它添加到QuickShopBagInstance(和ViewState)相同的值,ListView被正確填充,並且當您單擊刪除按鈕時它完美地作爲ViewState一直堅持。

現在,如果您將閱讀querystring位更改爲Page_InitComplete,而不是Page_Init,則它可以很好地工作。所以結論是...

你不能添加到VIEWSTATE之前Init_Complete !!!!!!!!

我多麼愚蠢,至少是誰寫的!

+0

這是:http://msdn.microsoft.com/en-us/library/ms178472.aspx是頁面生命週期中的事件的一個很好的資源;很少有幾次幫助過我。 – Dave

1

你似乎已經排除了大部分建議,到目前爲止我已經創建了一個基本的網頁,只有你上面提供的信息:

namespace SO_Questions 
{ 
    [Serializable()] 
    public class QuickShopBag 
    { 
     public string MyProperty { get; set; } 
    } 
} 

代碼背後

namespace SO_Questions 
{ 
    public partial class TestPage : System.Web.UI.Page 
    { 
     protected QuickShopBag QuickShopBagInstance 
     { 
      get { return (QuickShopBag)ViewState["QuickShopBag"]; } 
      set { ViewState["QuickShopBag"] = value; } 
     } 

     protected void Page_Load(object sender, EventArgs e) 
     { 
      if (!Page.IsPostBack) 
      { 
       this.QuickShopBagInstance = new QuickShopBag() { MyProperty = "Test String" }; 
      } 
      Message.Text = "Value is: " + this.QuickShopBagInstance.MyProperty.ToString(); 
     } 

     protected override void LoadViewState(object savedState) 
     { 
      base.LoadViewState(savedState); 
     } 

     protected void btnSubmit_Click(object sender, EventArgs e) 
     { 
      btnSubmit.Text += QuickShopBagInstance.MyProperty; 
     } 
    } 
} 

標記:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="SO_Questions.TestPage" ViewStateMode="Enabled" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"><title></title></head> 
<body> 
    <form id="form1" runat="server"><div> 
     <asp:Label ID="Message" runat="server"></asp:Label> 
     <asp:Button runat="server" ID="btnSubmit" Text="Submit" OnClick="btnSubmit_Click" /> 
    </div></form> 
</body></html> 

正如預期的那樣,這個運行正確;重寫的LoadViewState方法被擊中(並且viewstate正確地包含2項)並且按鈕的文本被更新。

合理的解釋是,別的地方還有別的東西在發生,或者你沒有提供額外的重要信息。

0

的東西,有我絆倒了,在過去是

  1. 在頁面
  2. 設置在ViewState的東西然後試圖在用戶控件進行檢索。找不到它 - 它去了哪裏?

看起來好像每個頁面應該有一個ViewState,但每個usercontrol都保留它自己的版本。

難道是這樣的?

SO link給我剛纔做了所有我想錯了的