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

推荐订阅源

P
Proofpoint News Feed
博客园 - 聂微东
Application and Cybersecurity Blog
Application and Cybersecurity Blog
MyScale Blog
MyScale Blog
罗磊的独立博客
H
Help Net Security
L
LangChain Blog
T
Threat Research - Cisco Blogs
量子位
S
Securelist
Last Week in AI
Last Week in AI
L
Lohrmann on Cybersecurity
T
The Exploit Database - CXSecurity.com
P
Privacy International News Feed
The Hacker News
The Hacker News
Vercel News
Vercel News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Blog of Author Tim Ferriss
T
Threatpost
Security Latest
Security Latest
P
Palo Alto Networks Blog
Microsoft Security Blog
Microsoft Security Blog
NISL@THU
NISL@THU
F
Full Disclosure
WordPress大学
WordPress大学
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Heimdal Security Blog
J
Java Code Geeks
Recorded Future
Recorded Future
Hugging Face - Blog
Hugging Face - Blog
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
阮一峰的网络日志
阮一峰的网络日志
U
Unit 42
B
Blog RSS Feed
月光博客
月光博客
C
Cisco Blogs
V
Visual Studio Blog
D
DataBreaches.Net
H
Hacker News: Front Page
博客园 - 叶小钗
N
News and Events Feed by Topic
爱范儿
爱范儿
A
Arctic Wolf

博客园 - Alex

Friends 104 COMPUWARE 如何用正确的方法来写出质量好的软件的75条体会[收藏]- - Cache的使用原则 C#:一种SQL Server XML和ASP.NET运行时应用程序 ASPX页Web服务调用性能优化 面向异步消息的Web应用(AMOWA) 关于网站减肥(网站板块异步加载技术) 选择自 changzheng 的 Blog Fxcop Windows Mobile开发环境搭建指南 获取滚动 Win2000命令全集 Form(思归):动态控件的状态问题 (From Msdn:)利用 ASP.NET Web 控件和数据绑定提升开发速度 (From CSDN) B/S开发常用JavaScript技术 (转)showModalDialog和showModelessDialog使用心得 ASP.NET 页面对象模型(转) Why does App restart? (FAQ) From 博客堂 Community Server技术分析——CS是如何将三个项目整合到一起的
思归的“动态控件的状态问题”的分析
Alex · 2005-03-31 · via 博客园 - Alex

希望写下这样的logic对大家做troubleshooting有所帮助。我们可以这样分析这个问题:

第一步,简化一下Page。建一个新的ASP.Net Web Application,用下面的code

private void Page_Load(object sender, System.EventArgs e)

{

        DropDownList ddlDynamic = new DropDownList();

        ddlDynamic.ID = "ddlDynamic";

        HtmlForm form1 = (HtmlForm)this.FindControl("Form1");

        if (!IsPostBack)

        {

                ddlDynamic.Items.Add("Before");

        }

        form1.Controls.Add(ddlDynamic);

        if (!IsPostBack)

        {

                ddlDynamic.Items.Add("After");

        }

}

Page上扔个Button,以便可以PostBack。运行后Postback的结果,“Before” item没被保留,“After”被保留了。问题被isolate:问题不在于DropDownList或者ListCollection对于view state的处理出问题,而是特定一个ListItem view state的处理有异。

现在有目标了,接下来看ListItem source code:

internal object SaveViewState()

{

      if (this.misc.Get(2) && this.misc.Get(3))

      {

            return new Pair(this.Text, this.Value);

      }

      if (this.misc.Get(2))

      {

            return this.Text;

      }

      if (this.misc.Get(3))

      {

            return new Pair(null, this.Value);

      }

      return null;

}

可以看到只有misc.Get(2)misc.Get(3)符合一定条件才存view state,鉴于miscprivate member,继续在ListItemcode里找什么会影响misc.Get(2) or misc.Get(3)的值,结果如下:

internal bool Dirty

{

       set

      {

            this.misc.Set(2, value);

            this.misc.Set(3, value);

      }

}

找到了唯一的可能,在Reflector里看Set方法的Callee Graph,找到System.Web.UI.WebControls.ListItemCollection.Add(ListItem):Void方法。接续看source code:

public void Add(ListItem item)

{

      this.listItems.Add(item);

      if (this.marked)

      {

            item.Dirty = true;

      }

}

这里有一个private bool marked flag。继续在ListItemCollection里找:

internal void TrackViewState()

{

      this.marked = true;

      for (int num1 = 0; num1 < this.Count; num1++)

      {

            this[num1].TrackViewState();

      }

}

void IStateManager.TrackViewState()

{

      this.TrackViewState();

}

好了,看来这个方法就是关键了……由于是Interface的方法,我们可以尝试一下在Page2里调用它:

((IStateManager)(ddlDynamic.Items)).TrackViewState();

if (!IsPostBack)
{
for (int i=1; i <=3; i++)
ddlDynamic.Items.Add(new ListItem(i.ToString(), i.ToString()));
}
form1.Controls.Add(ddlDynamic);

确实是起作用了……鉴于如此,我们可以猜测ControlCollection.Add一定调用了System.Web.UI.WebControls.ListItemCollection.TrackViewState()这个方法。要证明这点容易多了……

WinDbg,在System.Web.UI.WebControls.ListItemCollection.TrackViewState()方法上设个断点。Call Stack如下:

019cf8b0 06538fd0 [DEFAULT] [hasThis] Void System.Web.UI.WebControls.ListItemCollection.TrackViewState()
019cf8b4 06538fbe [DEFAULT] [hasThis] Void System.Web.UI.WebControls.ListControl.TrackViewState()
019cf8bc 06538e53 [DEFAULT] [hasThis] Void System.Web.UI.Control.InitRecursive(Class System.Web.UI.Control)
019cf8d8 0653758a [DEFAULT] [hasThis] Void System.Web.UI.Control.AddedControl(Class System.Web.UI.Control,I4)
019cf8f4 06537462 [DEFAULT] [hasThis] Void System.Web.UI.ControlCollection.Add(Class
System.Web.UI.Control)
019cf904 063c06fc [DEFAULT] [hasThis] Void WebApplication37.WebForm3.Page_Load(Object,Class System.EventArgs)
at [+0x13c] [+0x8c] c:\inetpub\wwwroot\webapplication37\webform3.aspx.cs:36
019cf944 065391a4 [DEFAULT] [hasThis] Void System.Web.UI.Control.OnLoad(Class System.EventArgs)

好了……一切都明了……