2011-12-02 18 views
8

Prawo, mam coś bardzo osobliwe dzieje tutaj ...stan wyświetlania jest zerowy na odświeżenie

ASP.NET 4 strona z następujących nieruchomości:

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

Podczas pierwszego Page_Load() w (! Page.IsPostBack) zapełniana jest pozycja QuickShopBagInstance i zapisano wartość ViewState.

Jednak podczas odświeżania strony strona ViewState jest pusta, gdy dostęp uzyskuje się za pomocą zdarzenia Backback Button_OnClick() !!!

Sprawdziłem Request.Form i na pewno wartość _Viewstate jest tam i jest wypełniona. Przepuściłem również tę wartość przez parser i zawiera ona oczekiwane dane, strona ma ViewStateEnabled = "true" i nową .NET 4 ViewStateMode = "Enabled".

Zmieniłem metodę LoadViewState, aby sprawdzić, czy uruchamia się, ale wygląda na to, że nie jest.

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

Naprawdę zagubiłem się, co może być problemem. Jakieś pomysły?

+0

Nie wyświetlasz logiki, której używasz do wypełnienia właściwości, która wprowadziła elementy do stanu widoku. Prawdopodobnie robi coś nie tak podczas post-back –

+1

Po prostu załóż to. QuickShopBagInstance = new QuickShopBag() przy początkowym załadowaniu. Powiedziałem również, że zweryfikowałem dane o wyświetleniu, które były przekazywane na poczcie zwrotnej, i to było poprawne. –

+0

Czy możesz opublikować definicję klasy QuickShopBag. Naprawdę nie potrzebuję właściwości. – Asken

Odpowiedz

9

Przede wszystkim byłem w błędzie, kod ten nie był w Page_Load ale w Page_Init, chociaż nie mam nic przeczytać, że mówi to możliwe” t przypisać do ViewState w Init.

Więc zebrała bardzo prosty test, który duplikuje problemy mam ...

<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>(); 
    } 
} 

Jeśli poprosisz powiedzieć „/quickshop.aspx?add1,add2,add3” ListView jest poprawnie wypełnione danymi z qs, jednak jeśli chodzi o kliknięcie przycisku usuwania, generowany jest wyjątek NullReferenceException, ponieważ obiekt ViewState nie zachował obiektu QuickShopBag.

Ale jeśli klikniesz przycisk "Dodaj", który jak widać dodaje do tych samych wartości do QuickShopBagInstance (i ViewState), ListView jest wypełniony poprawnie i po kliknięciu przycisku Usuń działa idealnie jako ViewState został uparty.

Teraz, jeśli zmienisz odczyt bitu kwerendy na Page_InitComplete w przeciwieństwie do Page_Init działa idealnie. Wniosek jest ...

NIE MOŻESZ DODAĆ DO WIDOKÓW PRZED Init_Complete !!!!!!!!

Jak głupio ode mnie, cóż, kto to napisał!

+0

To: http://msdn.microsoft.com/en-us/library/ms178472.aspx jest doskonałym źródłem zdarzeń w cyklu życia strony; pomógł mi przy kilku dobrych okazjach. – Dave

1

Wydaje się wykluczyć większość sugestii tak daleko, więc stworzyliśmy podstawową stronę tylko z Ciebie informacji powyżej:

klasy kod

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

za

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; 
     } 
    } 
} 

markup:

<%@ 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> 

Zgodnie z oczekiwaniami to działa poprawnie; zastępowana metoda LoadViewState jest trafiona (a funkcja wyświetlania poprawnego zawiera 2 elementy), a tekst przycisku jest aktualizowany.

Logicznym wytłumaczeniem byłoby, że coś innego dzieje się gdzieś indziej lub nie udało się dostarczyć dodatkowej, istotnej informacji.

0

Coś zadziałał mi się w przeszłości jest

  1. Ustawianie coś w ViewState na stronie
  2. Następnie próbuje pobierać go w kontroli użytkownika. Nie mogę tego znaleźć - gdzie to się podziało?

Wygląda na to, że powinieneś mieć jedno ViewState na stronę, ale każda kontrola użytkownika zachowuje własną wersję.

Czy to może być coś takiego?

Ten SO link daje lepsze wyjaśnienie, że mam tylko zrobić

Powiązane problemy