2011-12-02 32 views
8

Phải, tôi đã có cái gì đó rất đặc biệt xảy ra ở đây ...ViewState là null trên postback

ASP.NET 4 trang với các tài sản sau đây:

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

Trong Page_Load ban đầu() trong (! Page.IsPostBack) QuickShopBagInstance được điền và ViewState được lưu.

Tuy nhiên, khi bạn thực hiện đăng lại trên trang, ViewState sẽ trống khi được truy cập từ sự kiện Button_OnClick() postback sau!

Tôi đã kiểm tra Request.Form và chắc chắn đủ giá trị _Viewstate ở đó và được điền. Tôi cũng đã chạy giá trị này thông qua một trình phân tích cú pháp và nó chứa dữ liệu dự kiến, trang có ViewStateEnabled = "true" và .NET 4 ViewStateMode = "Enabled" mới.

Tôi đã chuyển sang ghi đè phương thức LoadViewState để kiểm tra xem nó có đang kích hoạt hay không.

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

Tôi thực sự bị mất như những gì có thể có thể là vấn đề. Bất kỳ ý tưởng?

+0

Bạn không hiển thị logic bạn đang sử dụng để điền thuộc tính đưa nội dung vào chế độ xem. Probabily nó làm gì đó sai trong thời gian sau lưng –

+1

Chỉ cần giả định this.QuickShopBagInstance = new QuickShopBag() trên tải ban đầu. Tôi cũng đã nói rằng tôi đã xác nhận hợp lệ dữ liệu ViewState đã được chuyển vào postback và đó là chính xác. –

+0

Bạn có thể vui lòng đăng định nghĩa lớp QuickShopBag không. Không thực sự cần các thuộc tính. – Asken

Trả lời

9

Trước hết tôi đã nhầm, các mã trong câu hỏi không phải là trong Page_Load nhưng trong Page_Init, mặc dù tôi đã không đọc bất cứ điều gì nói rằng bạn có thể' t gán cho ViewState tại Init.

Vì vậy, tôi đặt cùng một thử nghiệm rất cơ bản mà bản sao những vấn đề tôi đang gặp ...

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

Nếu bạn yêu cầu nói "/quickshop.aspx?add1,add2,add3", ListView là cư trú chính xác với dữ liệu từ các qs, tuy nhiên khi nói đến cách nhấn vào nút xóa một NullReferenceException được ném vì ViewState đã không tồn tại đối tượng QuickShopBag. Tuy nhiên, nếu bạn nhấp vào nút "Thêm", bạn có thể thấy thêm vào cùng giá trị cho QuickShopBagInstance (và ViewState), ListView được điền chính xác và khi bạn nhấp vào nút Xóa, nó hoạt động hoàn hảo như ViewState đã được tiếp tục tồn tại.

Bây giờ, nếu bạn thay đổi việc đọc bit chuỗi truy vấn thành Page_InitComplete như trái ngược với Page_Init, nó hoạt động hoàn hảo. Vì vậy, kết luận là ...

BẠN KHÔNG THỂ THÊM VÀO XEM TRƯỚC KHI Init_Complete !!!!!!!!

Làm thế nào ngớ ngẩn của tôi, bất kỳ ai cũng viết ít nhất!

+0

Điều này: http://msdn.microsoft.com/en-us/library/ms178472.aspx là tài nguyên tuyệt vời cho các sự kiện trong vòng đời của trang; đã giúp tôi một vài lần. – Dave

1

Bạn dường như đã loại trừ khả năng hầu hết các ý kiến ​​cho đến nay vì vậy tôi đã tạo ra một trang cơ bản chỉ với những thông tin mà bạn đã cung cấp ở trên:

lớp

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

mã sau

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

đánh dấu:

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

Như dự kiến, điều này chạy đúng; phương thức LoadViewState bị ghi đè được nhấn (và viewstate chứa đúng 2 mục) và văn bản của nút được cập nhật.

Giải thích hợp lý sẽ là có điều gì khác đang diễn ra ở một nơi khác hoặc bạn không thể cung cấp thêm thông tin nổi bật.

0

Cái gì đó đã vấp tôi trong quá khứ là

  1. Thiết cái gì đó trong ViewState trong trang
  2. Sau đó cố gắng để lấy lại nó trong một điều khiển người dùng. Không thể tìm thấy nó - nó đã biến mất ở đâu?

Dường như bạn nên có một ViewState trên mỗi trang nhưng mỗi người dùngcontrol giữ phiên bản riêng của nó.

Có thể giống như thế này không?

SO link này đưa ra một lời giải thích tốt hơn mà tôi đã thực hiện

Các vấn đề liên quan