default2.aspx
synchronize
FavIcon.ascx
<%@ Page Language="C#" AutoEventWireup="true" Theme="Blue" %>
<%@ Register TagPrefix="uc1" TagName="favicon" Src="~/FavIcon.ascx" %>
<!DOCTYPE html>
<script runat="server">
private void Page_PreRender(object sender, System.EventArgs e)
{
HtmlGenericControl scriptControl = new HtmlGenericControl("script");
Page.Header.Controls.AddAt(0, scriptControl);//If this line is commented out, no exception will occur.
}
private void Page_Init(object sender, System.EventArgs e)
{
ScriptManager oSM = new ScriptManager();
Page.Form.Controls.Add(oSM);//If this line is commented out, no exception will occur.
}
</script>
<html>
<head runat="server">
<title></title>
<uc1:favicon runat="server"></uc1:favicon>
</head>
<body>
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" />
</form>
</body>
</html>
还要在Blue主题中添加样式表。
页面打开成功,但是一旦我点击按钮,它就会抛出异常
无法加载视图状态。 viewstate所在的控制树 正在加载必须与用于保存的控制树匹配 在上一个请求期间查看状态。例如,添加时 动态控制,回发期间添加的控件必须匹配 初始期间添加的控件的类型和位置 请求。
有谁可以解释为什么会发生这种错误?
答案 0 :(得分:1)
由于ViewState的性质,它发生了。简而言之,当您的页面被回发时,恢复ViewState的控件将与控件索引匹配,因此当索引更改时会导致此问题。
在这种情况下,为您的网页设置属性ViewStateMode="Disabled"
或更改添加动态元素Page.Header.Controls.AddAt(Page.Header.Controls.Count, scriptControl)
的顺序,这样可以避免干扰已恢复元素的顺序,可以帮助您应对麻烦。至少,它适合我。
答案 1 :(得分:1)
要调试这些错误,我强烈建议启用跟踪(@page指令中的Trace =“true”,或使用global setting in web.config),这样就可以看到服务器的控制树。
在GET上,控制树就是这样(注意自动生成的唯一ID):
HtmlHead
+ ctl05 : HtmlGenericControl (from your PreRender code)
+ ctl01 : Title (the <title> tag)
+ ctl02 : FavIcon (your favicon.ascx)
+ ctl04 : HtmlLink (from the 'Blue' theme)
HtmlForm
+ ctl03 : ScriptManager
“无法加载ViewState”错误的根本原因是:
生成的ID遵循ASP.NET的lifecycle order:
ASP.NET ViewState引擎是树序列化器/反序列化器。树中的每个节点都有它的ID,以及由其父ID和自己的ID组成的“完整ID”。当然,只要您在序列化和反序列化之间更改ID,所有投注都会关闭,引擎会检测到它并引发“Failed to Load ViewState”错误。
因此,如果你放Visible=false
,你将使用ViewState。如果你删除它,你就不会。当您自己不使用ViewState时,获取“无法加载视图状态”错误的可能性较小,但是当您使用其所有功能(主题等)时,ASP.NET可以代表您使用某些ViewState。在Visible的情况下,它只意味着控件存在(并使用ViewState),但不渲染(它的渲染大小为0)。但是你会看到使用ViewState的任何其他属性的问题,它不是特定于Visible属性(你也可以尝试this.ViewState["test"] = "whatever"
)。
如果您将<uc1:favicon runat="server"></uc1:favicon>
放在页面的其他位置,它也会起作用,因为它不再位于Head控制树中,并且不会干扰Theme的链接或动态控件。
对于Theme和ScriptManager,只是当你玩它们时,它会改变或不改变ID,系统可能会检测到它。
有许多方法可以打破ViewState。什么是非常困难的,它似乎不应该工作(例如,只要你不使用FavIcon的ViewState,你没有注意到你的代码有问题。)