2011-12-02 7 views
8

derecho, tengo algo muy peculiar pasando aquí ...Viewstate es nulo en la devolución de datos

ASP.NET 4 página con la siguiente propiedad:

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

Durante el Page_Load inicial() en (! Page.IsPostBack) se completa QuickShopBagInstance y se guarda ViewState.

Sin embargo, cuando realiza una devolución de datos en la página, ViewState está vacío cuando se accede desde el evento Postback Button_OnClick() !!!

He comprobado el Request.Form y, con seguridad, el valor _Viewstate está allí y está lleno. También ejecuté este valor a través de un analizador y contiene los datos esperados, la página tiene ViewStateEnabled = "true" y el nuevo .NET 4 ViewStateMode = "Enabled".

He pasado a anular el método LoadViewState para comprobar si se está disparando, no parece ser así.

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

Estoy realmente perdido en cuanto a lo que podría ser el problema. ¿Algunas ideas?

+0

No muestra la lógica que está utilizando para rellenar la propiedad que coloca cosas en viewstate. Probablemente hace algo mal durante el post-back –

+1

Simplemente asuma esto. QuickShopBagInstance = new QuickShopBag() en la carga inicial. También dije que había validado los datos de viewstate que se estaban transfiriendo a la devolución de datos y que era correcto. –

+0

¿Puede publicar la definición de la clase QuickShopBag? Realmente no necesito las propiedades. – Asken

Respuesta

9

En primer lugar yo estaba equivocada, el código en cuestión no estaba en Load pero en Page_Init, aunque no he leído nada que diga que puede' t asignar a ViewState en Init.

por lo que poner juntos una prueba muy básica que duplica los problemas que tengo ...

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

Si solicita decir "/quickshop.aspx?add1,add2,add3", es el ListView poblado correctamente con los datos de la qs, sin embargo, cuando se trata de hacer clic en el botón Eliminar, se lanza una NullReferenceException porque ViewState no ha persistido en el objeto QuickShopBag.

Pero si hace clic en el botón "Agregar" que como puede ver agrega los mismos valores a QuickShopBagInstance (y ViewState), ListView se completa correctamente y al hacer clic en el botón Eliminar funciona perfectamente como ViewState ha sido persistido

Ahora si cambia la lectura del bit de la cadena de consulta a Page_InitComplete en lugar de a Page_Init, funciona perfectamente. Entonces, la conclusión es ...

NO PUEDE AGREGARSE A LA VISUALIZACIÓN ANTES Init_Complete !!!!!!!!

¡Qué tonto de mí, bueno, quien sea que lo haya escrito al menos!

+0

Esto: http://msdn.microsoft.com/en-us/library/ms178472.aspx es un gran recurso para eventos en el ciclo de vida de la página; me ayudó en algunas buenas ocasiones. – Dave

1

Usted parece haber descartado la mayoría de las sugerencias hasta el momento por lo que hemos creado una página básica con solamente la información que ha proporcionado anteriormente:

clase de código

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

detrás

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

marcado:

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

Como era de esperar, esto funciona correctamente; el método LoadViewState reemplazado es hit (y viewstate contiene correctamente 2 elementos) y el texto del botón se actualiza.

La explicación lógica sería que hay algo más que sucede en otro lugar o que no ha proporcionado una información adicional importante.

0

Algo que me ha disparado en el pasado es

  1. Ajuste algo en el ViewState en la página
  2. luego tratar de recuperarlo en un control de usuario. No puedo encontrarlo, ¿a dónde se fue?

Parece que debería tener un ViewState por página pero cada usercontrol mantiene su propia versión.

¿Podría ser algo como esto?

Este SO link da una mejor explicación que acabo de hacer

Cuestiones relacionadas