我想在Render时对页面的所有{}中的内容进行修改替换,当使用了UpdatePanel进行异步回发之后,会报一个这样的错误:
这里我们先重温了一下UpdatePanel的原理:首先ScriptManager和UpdatePanel在服务器端达成一致,截获了Page的Render()方法并在页面上为需要进行异步回送的控件输出了一些专门的JavaScript脚本。然后在客户端,若这些控件通过_doPostBack()函数试图引发整页的回送,则上面提到的JavaScript脚本将截获这个调用,并将页面中各个用户输入的控件的值,加上当前的试图状态 (ViewState)用XMLHttpRequest对象发送服务器。而此时服务器却对此丝毫不知,仍把它当作一次传统的回发,老老实实地引发了一次完整生命周期,并根据回送生成新的页面结构。随后又是在Page的()方法中,ScriptManager和UpdatePanel再次获取了其中的实现过程,把不在UpdatePanel中的内容统统踢出,只发送给客户端震泽更新的部分。最后,客户端的XMLHttpRequest对象收到了这部分信息,并在不知不觉悄悄地更新了UpatePanel中定义的内容。
所以我想可能是返回给客户端的内容中有保持文件一致性的内容,我们先看一下回发到客户端的html内容
Code
718|updatePanel|UpdatePanel1|<span id="Label1">asdf</span>
<div>
<table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;">
<tr>
<th scope="col">中国</th><th scope="col">美国</th>
</tr><tr>
<td>哈哈</td><td> </td>
</tr><tr>
<td>英文</td><td> </td>
</tr><tr>
<td colspan="2"><table border="0">
<tr>
<td><a href="javascript:__doPostBack('GridView1','Page$1')">1</a></td><td><span>2</span></td><td><a href="javascript:__doPostBack('GridView1','Page$3')">3</a></td><td><a href="javascript:__doPostBack('GridView1','Page$4')">4</a></td><td><a href="javascript:__doPostBack('GridView1','Page$5')">5</a></td>
</tr>
</table></td>
</tr>
</table>
</div>
|0|hiddenField|__EVENTTARGET||0|hiddenField|__EVENTARGUMENT||332|hiddenField|__VIEWSTATE|/wEPDwUILTY5NTIwMTYPZBYCAgMPZBYCAggPZBYCZg9kFgRmDw8WAh4EVGV4dAUEYXNkZmRkAgIPPCsADQEADxYEHgtfIURhdGFCb3VuZGceC18hSXRlbUNvdW50AgpkFgJmD2QWBgIBD2QWBGYPDxYCHwAFBuWTiOWTiGRkAgEPDxYCHwAFBiZuYnNwO2RkAgIPZBYEZg8PFgIfAAUG6Iux5paHZGQCAQ8PFgIfAAUGJm5ic3A7ZGQCAw8PFgIeB1Zpc2libGVoZGQYAQUJR3JpZFZpZXcxDzwrAAkCAgIBCAIFZFTnIwxlHaXjAyBLi66gUdaNiabH|104|hiddenField|__EVENTVALIDATION|/wEWCQLz1JrEAwKtsuq4BAKtsuK4BAKtsva4BAKtsvq4BAKyou7OAgKyosaYAQKyor67BQKM54rGBn7w/tljZyMLEZhx0nYyW+jcIW9o|0|asyncPostBackControlIDs|||0|postBackControlIDs|||13|updatePanelIDs||tUpdatePanel1|0|childUpdatePanelIDs|||12|panelsToRefreshIDs||UpdatePanel1|2|asyncPostBackTimeout||90|12|formAction||default.aspx|4|pageTitle||无标题页|
开始我以为这个保持一致的内容可能是在后边的viewstate中,经过对起解码(使用这个工具解码)并没发现什么有价值的东西,正在我一筹莫展时,一个兄弟终于揭开了谜团,原来第一个|前的这个数字是回发的字符串长度,就是我们上边那个例子中718,我们篡改内容时必须要重新计算这个数字,把程序改下:
Code
protected override void Render(HtmlTextWriter writer)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Reset();
stopwatch.Start();
try
{
//会把页面的输出结果存储在这个StringBuilder中
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter htw = new HtmlTextWriter(sw);
base.Render(htw);
string content = sb.ToString();
var splitStr = content.Split('|');
if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
int x = Convert.ToInt32(content.Substring(0, content.IndexOf('|')));
for (int i = 0; i < splitStr.Length; i++)
{
if (Convert.ToInt32(splitStr[0]) == splitStr[i].Length)
{
splitStr[i] = RenderTag(splitStr[i]);
splitStr[0] = splitStr[i].Length.ToString();
break;
}
}
string tt = null;
foreach (var item in splitStr)
{
tt += item + '|';
}
content = tt.Substring(0, tt.LastIndexOf('|'));
}
content = RenderTag(content);
//重新写入页面
writer.Write(content);
}
catch (Exception ex)
{
//Response.Write(ex.ToString());
Response.End();
}
finally
{
stopwatch.Stop();
Response.Write("runtime:" + stopwatch.ElapsedMilliseconds.ToString() + "ms");
}
}