首先我弄错了,有问题的代码不在 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 的数据,但是当单击删除按钮时会抛出 NullReferenceException,因为 ViewState 没有t 持久化 QuickShopBag 对象。
但是,如果您单击“添加”按钮,如您所见,该按钮会将相同的值添加到 QuickShopBagInstance(和 ViewState),ListView 会正确填充,并且当您单击删除按钮时,它会像 ViewState 一样完美运行被持久化了。
现在,如果您将读取查询字符串位更改为 Page_InitComplete 而不是 Page_Init 它可以完美运行。所以结论是……
您不能在 Init_Complete 之前添加到 VIEWSTATE !!!!!!!!!
我真傻,至少是谁写的!