Здраствуйте! Нашел багу в ASP.NET, она репродюсится по крайней мере для IE7 и связана с тем, что на postback приходит начальный ViewState, а не текущий.
1. Приложение
Создаю вебсайт с одной станичкой, версия .NET Framework 3.5.
В этой страниче пишу такой код на Markup'e:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!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 id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div>
<asp:Repeater ID="Repeater1" runat="server" EnableViewState="false">
<HeaderTemplate>
<asp:TextBox ID="AddText" runat="server"></asp:TextBox>
<asp:Button ID="AddButton" runat="server" Text="Add"></asp:Button>
<br />
</HeaderTemplate>
<ItemTemplate>
<asp:HiddenField ID="HiddenField1" runat="server"></asp:HiddenField>
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:Button ID="DeleteButton" runat="server" Text="Delete"></asp:Button>
</ItemTemplate>
</asp:Repeater>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Code behind следующий:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
List<string> Lines
{
get
{
return (List<string>)ViewState["Lines"];
}
set
{
ViewState["Lines"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Lines = new List<string>() { "First", "Second" };
}
Repeater1.ItemDataBound += Repeater1_ItemDataBound;
BindLines();
AddLineButton.Click += AddLineButton_Click;
}
private void BindLines()
{
Repeater1.DataSource = Lines;
Repeater1.DataBind();
}
void AddLineButton_Click(object sender, EventArgs e)
{
Lines.Add(AddLineTextBox.Text);
BindLines();
}
private Button AddLineButton
{
get
{
List<Control> res = FindControls(Repeater1.Controls, item => ((RepeaterItem)item).ItemType == ListItemType.Header);
return (Button)res[0].FindControl("AddButton");
}
}
private TextBox AddLineTextBox
{
get
{
List<Control> res = FindControls(Repeater1.Controls, item => ((RepeaterItem)item).ItemType == ListItemType.Header);
return (TextBox)res[0].FindControl("AddText");
}
}
private void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item)
return;
Label label = (Label)e.Item.FindControl("Label1");
label.Text = (string)e.Item.DataItem;
Button deleteButton = (Button)e.Item.FindControl("DeleteButton");
deleteButton.Command += deleteButton_Command;
deleteButton.CommandArgument = e.Item.ItemIndex.ToString();
}
private void deleteButton_Command(object sender, CommandEventArgs e)
{
int index = int.Parse(e.CommandArgument.ToString());
Lines.RemoveAt(index);
BindLines();
}
private List<Control> FindControls(System.Web.UI.ControlCollection controls, Predicate<Control> match)
{
List<Control> res = new List<Control>();
foreach (Control control in controls)
{
if (match(control))
res.Add(control);
}
return res;
}
}
}
2. Как репродюсить: Открыть IE7, увидеть две строки которые можно удалить, удалить одну, зайти в текстовое поле, написать текст, нажать
два раза Esc, текст очищается, написать текст (можно другой), нажать добавить. В результате видим три строки вместо двух.
Внимание, вопрос! Как это пофиксить?