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

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
LINUX DO - 热门话题
S
Secure Thoughts
TaoSecurity Blog
TaoSecurity Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threat Research - Cisco Blogs
AI
AI
B
Blog RSS Feed
S
Schneier on Security
雷峰网
雷峰网
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
Cloudbric
Cloudbric
L
LINUX DO - 最新话题
罗磊的独立博客
有赞技术团队
有赞技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News
博客园 - Franky
Attack and Defense Labs
Attack and Defense Labs
The Cloudflare Blog
Webroot Blog
Webroot Blog
Last Week in AI
Last Week in AI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 叶小钗
美团技术团队
L
Lohrmann on Cybersecurity
T
The Blog of Author Tim Ferriss
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Vercel News
Vercel News
Know Your Adversary
Know Your Adversary
O
OpenAI News
博客园 - 【当耐特】
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cybersecurity and Infrastructure Security Agency CISA
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
PCI Perspectives
PCI Perspectives
H
Heimdal Security Blog
I
InfoQ
GbyAI
GbyAI
T
Threatpost
C
Cisco Blogs

博客园 - hgtj

谈谈产品和项目 重新开始写博客 组件 访问被拒绝 --“/”应用程序中的服务器错误。IIS重启不行,系统注销也不行 (转).Net 揭密--JIT怎样运行你的代码 第一部分 (普通调用) MS-SQLSERVER数据库SUSPECT状态如何解决 Com Interop入门 可按任意字段排序的分页存储过程(转) 拨开SOA的面纱(一篇对SOA概念讲解的很透彻的文章) 基于角色管理的系统访问控制 MySQL查询优化系列讲座之查询优化器 SQL语句优化技术分析 对ORM的疑问 MonoRail - 生命周期及controller/action/view详解 (转) 了解AOP(转) 接口的终结解释 (转) Asp.Net 背后原理 关于类型转换方面的备忘 java设计模式之State(转) javascript 实现类似C#中字符串的Trim()方法
思归的“动态控件的状态问题”的分析
hgtj · 2006-04-21 · via 博客园 - hgtj

思归的“动态控件的状态问题”很有意思:XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

http://blog.joycode.com/saucer/archive/2004/10/20/35927.aspx

希望写下这样的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)

好了……一切都明了……