惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
The GitHub Blog
The GitHub Blog
美团技术团队
Know Your Adversary
Know Your Adversary
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Register - Security
The Register - Security
Stack Overflow Blog
Stack Overflow Blog
Attack and Defense Labs
Attack and Defense Labs
G
Google Developers Blog
I
InfoQ
博客园 - 司徒正美
T
Troy Hunt's Blog
Google DeepMind News
Google DeepMind News
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
S
Security Affairs
M
MIT News - Artificial intelligence
Simon Willison's Weblog
Simon Willison's Weblog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Tailwind CSS Blog
量子位
Vercel News
Vercel News
月光博客
月光博客
V
Vulnerabilities – Threatpost
N
News and Events Feed by Topic
Hugging Face - Blog
Hugging Face - Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
L
LangChain Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 最新话题
F
Full Disclosure
The Hacker News
The Hacker News
Hacker News: Ask HN
Hacker News: Ask HN
T
Tor Project blog
A
Arctic Wolf
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Forbes - Security
Forbes - Security
IT之家
IT之家
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Y
Y Combinator Blog
GbyAI
GbyAI
B
Blog RSS Feed
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs

博客园 - sunrack

LINQ to SQL语句之Group By/Having和Exists/In/Any/All/Contains ASPxPopupControl does not show up in the right place C++/CLI托管字符串与非托管char数组的转换 程序员从初级到中级10个秘诀 Get JavaScript IntelliSense With DevExpress Client-Side Objects - v2010 vol 1 Grid Editing - Cascading Combo Boxes - sunrack ASPxRadioButtonList 报错解决办法 - sunrack - 博客园 本地连接属性“出现意外错误”的解决办法 - sunrack - 博客园 Bootstrap DotNetFX35SP1 in Visual Studio 2010 Windows Server 2008 共享策略 XtraPivotGrid Custom Summaries 手动注册 DevExpress 8.2.3 控件到 Visual Studio 工具箱 sn.exe error "Failed to generate a strong name key pair -- The keyset is not defined" Thread Tools Rate Thread 浅析JavaScript中的showModalDialog的实战应用 javascript showModalDialog模态对话框使用说明 - sunrack - 博客园 entity framework 缓存干扰的数据不一致问题 ViewState and Dynamic Control ASPxGridView 和 AJAX Extensions ToolBox 不兼容 ASPxCombobox Features
Failed to load viewstate ? Typical problem, with an obvious solution.
sunrack · 2010-05-18 · via 博客园 - sunrack

Understanding viewstate is fundamental in asp.net, especially if you had run into :

Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.

The only way to resolve is a proper understanding of viewstate.

http://geekswithblogs.net/FrostRed/archive/2007/02/17/106547.aspx is a interesting post on viewstate that i happen to read today, pointed out to me by someone who ran into a viewstate problem about the control tree not matching and was clearly afraid of adding controls dynamically after reading some facts presented in that article. Who wouldn't :-)

While the post gives us a very good understanding of viewstate and how it can fail, so i encourage you to read it first, might seem lengthy but I assure  you, it's quite interesting. However, when you're done, follow my rant here, since I feel it's important to know, that, the failure can only happen when either done deliberately as per the sample code in the post i linked to above or to *not* understanding viewstate and how it works.

So how can we easily avoid these failures ? Let's look at his first code example, and build onto that :

protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
Button btnClickMe = new Button();
form1.Controls.Add(btnClickMe);
btnClickMe.Text = "Click me";
}
else
{
Label label = new Label();
form1.Controls.Add(label);
}
}

As you can note above, this is problematic, since the control into which viewstate is restored is matched by control index, so when the index changes, as is clear in the above code, because if btnClickMe was loaded in for example index [0], now upon postback, after the page has been recreated and rebuilt, the Label "label" is loaded in index [0] instead and takes the place of the button. So this means viewstate that was meant for the button is loaded into the label instead, and the output in the screen after clicking the button is "click me" which was clearly not provided to the label's text property.

Now that we understand the problem, how can this sample apply in real world or why would anybody want to do something like this ? Basically in short, why is viewstate being utilized, if it's not needed after postback ? Button btnClickMe is not reloaded after postback, so it's safe to turn off viewstate on this control, and problem is solved.

This is a typical situation where you deliberately want viewstate to fail, apart from that i see no real use to want to maintain viewstate, which is also bloat on a control that clearly is not utilizing it.

so a rewrite ? here :

protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
Button btnClickMe = new Button();
// note the addition of the following line
btnClickMe.EnableViewState = false;
form1.Controls.Add(btnClickMe);
btnClickMe.Text = "Click me";
}
else
{
Label label = new Label();
form1.Controls.Add(label);
}
}

Otherwise, again as per the sample code above, had we been using viewstate, then the problem would resolve itself, if we recreated the control also after postback, which is one of the basic rules of dynamic controls creation. I say rules but really it's the logical thing to do since the page is destroyed after postback and asp.net will have no recollection of controls you added dynamically since memory is cleared, so it's upto you to build it up again manually :-)

protected void Page_Init(object sender, EventArgs e)
{
// button will be created even after postback
Button btnClickMe = new Button();
btnClickMe.EnableViewState = false;
form1.Controls.Add(btnClickMe);
btnClickMe.Text = "Click me";
if (IsPostBack)
{
Label label = new Label();
form1.Controls.Add(label);
}
}

So, bottom line, a proper understanding of viewstate, knowledge of the page life cycle, so you know in what phase it's safe to build your control, which will guarantee that viewstate is reloaded into the control(so you load it prior to page_load), and you got it right. For a proper understanding of the page life cycle, you can read the following document on msdn : http://msdn2.microsoft.com/en-us/library/ms178472.aspx?wt.slv=ColumnA

Update Jan/04/2008: I forgot to mention a gotcha, so here it is :  

Another gotcha you want to avoid is also the order of controls, that is, when you're loading a dynamic control, make sure the order in which you create it, has the same order when you recreate it. Confused, here let me explain better :

protected void Page_Init(object sender, EventArgs e)
{
if (IsPostBack)
{
Label label = new Label();
label.ID = "label1";
form1.Controls.Add(label);
label.Text = "label";

Button btnClickMe = new Button();
btnClickMe.ID = "button1";
form1.Controls.Add(btnClickMe);
btnClickMe.Text = "Click me";

}
else if (!IsPostBack)
{
//Now lets change the order
//during postback and we are
//recreating the controls
Button btnClickMe = new Button();
btnClickMe.ID = "button1";
form1.Controls.Add(btnClickMe);
btnClickMe.Text = "Click me";

Label label = new Label();
label.ID = "label1";
form1.Controls.Add(label);
label.Text = "label";
}
}

As you can note above, the order in which controls are added changes after postback. In this scenario what really happens ? The viewstate meant for the button is loaded into the label and the viewstate meant for the label is loaded into the button. So, you really want to be careful with the order in which you recreate your controls.