当更新面板中的回发发生得太快时,似乎 ASP.NET 客户端 JavaScript 有一个错误,即它发送到服务器的正文不等于 HTTP 标头中的内容长度。当视图状态变量被截断时,这会导致 IIS 7.5 抛出“无效的 base-64”异常(对于我的特定应用程序)。Fiddler 跟踪显示 HTTP 请求实际上格式错误。
在我的生产案例中(它发生在不止一页上),这是由于视图状态非常大。是的,我可以修剪或完全摆脱它。但问题是有谁知道为什么客户会截断身体以及如何避免它?
鉴于我没有添加任何自己的 JavaScript,在我看来,错误在于 MS 客户端 JavaScript。请注意,我只在 IE8/9 和 Chrome 而不是 Firefox 中触发了它——也许 Firefox 使用不同的套接字库(仍然是 nspr)?
以下是我试图说明问题的示例。我在“网站”中添加了该页面,并且正在使用带有 .Net 4 的 VS10。我可以使用 IIS7.5 和 VS10 内置 Web 服务器来触发该问题。这个例子通常会在 64k(精确)处截断,但我的生产页面会有所不同。
在 Default.aspx 中:
<asp:UpdatePanel ID="up" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblResult" runat="server" />
<asp:Repeater ID="rptCheckBoxes" runat="server">
<ItemTemplate>
<br />
<asp:CheckBox ID="cbOne" runat="server"
AutoPostBack="true"
OnCheckedChanged="cb_OnCheckChanged"
Text='<%# Eval("thing") %>' />
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
在 Default.aspx.cs 中:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var things = new List<Thingy>();
for (int i = 0; i < 5000; i++)
{
things.Add(new Thingy { Thing = i.ToString() });
}
rptCheckBoxes.DataSource = things;
rptCheckBoxes.DataBind();
}
}
protected void cb_OnCheckChanged(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
if (cb.Checked)
{
lblResult.Text = cb.Text;
}
else
{
lblResult.Text = "not checked";
}
}
internal class Thingy
{
public string Thing { get; set; }
}
运行 Fiddler,快速单击复选框,最终显示格式错误的 HTTP 请求。