C# 删除页面加载控件时ASP.NET问题

C# 删除页面加载控件时ASP.NET问题,c#,asp.net,C#,Asp.net,我有以下Index.aspx web表单: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ProblematicWebApplication.Index" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xht

我有以下Index.aspx web表单:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ProblematicWebApplication.Index" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <asp:Label ID="dummyLabel" runat="server" Text="This is dummy label." />
    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="intDropDownList" runat="server"/>
        <br />
        <asp:Button Text="Submit" OnClick="OnSubmitClicked" runat="server"/>
        <br />
        Selected value: <asp:Label ID="selectedValueLabel" runat="server" />
    </div>
    </form>
</body>
</html>
当我运行应用程序时,查询字符串中没有删除伪参数,并从intDropDownList中选择一些值,然后单击Submit按钮,所选值将相应地显示在selectedValueLabel中

但如果我在查询字符串中使用remove dummy=1参数运行应用程序,dummyLabel将被删除。现在,当我从intDropDownList中选择一些值并单击Submit按钮时,所选值未正确写入selectedValueLabel,intDropDownList中的所有项目都已删除

有人能解释一下为什么会这样吗?
为什么删除无关的dummyLabel控件会对intDropDownList控件产生影响?

Hmm,似乎有些奇怪。我通过将您的代码移动到页面的
PreInit
事件中来实现这一点:

protected void Page_PreInit(object sender, EventArgs e)
{
    if (this.Request["remove-dummy"] != null)
    {
        this.Controls.Remove(this.dummyLabel);
    }
}

嗯,看起来很奇怪。我通过将您的代码移动到页面的
PreInit
事件中来实现这一点:

protected void Page_PreInit(object sender, EventArgs e)
{
    if (this.Request["remove-dummy"] != null)
    {
        this.Controls.Remove(this.dummyLabel);
    }
}

在上一次页面加载中删除dummyLabel后,在回发中似乎ViewState加载失败

详情:

第一项研究包括以下文章:

下图显示了重要的ASP.NET页面事件以及ViewState处理发生的位置

那么,当声明性控件dummyLabel被删除时会发生什么呢?以下是一个过程:

  • 首次使用查询字符串参数remove dummy=1请求页面
  • 在页面中,加载事件声明性控件dummyLabel被删除
  • 在SaveStateComplete事件之前,将保存ViewState。控件树中没有控件dummyLabel,因此不会保存其ViewState
  • 单击提交按钮
  • 在InitComplete和PreLoad事件之间,将加载ViewState。这是它中断的原因,因为控件树现在包含dummyLabel(在加载事件中,dummyLabel在加载后被删除),并且ASP.NET无法将ViewState递归加载到页面控件树中。我的假设是ViewState和页面控制树是紧密耦合的,递归ViewState加载由于这种紧密耦合而失败
  • 还有一种情况支持这一理论:如果将dummyLabel放在页面的最末尾,问题就不会再发生了,因为页面控件树中位于dummyLabel之前的所有其他控件都已经从ViewState中选择了正确的值(ViewState结构和页面控件树紧密耦合)。如果在dummyLabel之后有更多控件,则它们的ViewState加载将失败


    要解决此问题,必须在ViewState加载之前删除所有应该删除的声明性控件(在ASPX文件中定义),无论是在InitComplete事件中还是在它之前的任何其他事件中

    在上一次页面加载中删除dummyLabel后,回发中的ViewState加载似乎失败了

    详情:

    第一项研究包括以下文章:

    下图显示了重要的ASP.NET页面事件以及ViewState处理发生的位置

    那么,当声明性控件dummyLabel被删除时会发生什么呢?以下是一个过程:

  • 首次使用查询字符串参数remove dummy=1请求页面
  • 在页面中,加载事件声明性控件dummyLabel被删除
  • 在SaveStateComplete事件之前,将保存ViewState。控件树中没有控件dummyLabel,因此不会保存其ViewState
  • 单击提交按钮
  • 在InitComplete和PreLoad事件之间,将加载ViewState。这是它中断的原因,因为控件树现在包含dummyLabel(在加载事件中,dummyLabel在加载后被删除),并且ASP.NET无法将ViewState递归加载到页面控件树中。我的假设是ViewState和页面控制树是紧密耦合的,递归ViewState加载由于这种紧密耦合而失败
  • 还有一种情况支持这一理论:如果将dummyLabel放在页面的最末尾,问题就不会再发生了,因为页面控件树中位于dummyLabel之前的所有其他控件都已经从ViewState中选择了正确的值(ViewState结构和页面控件树紧密耦合)。如果在dummyLabel之后有更多控件,则它们的ViewState加载将失败


    要解决此问题,必须在ViewState加载之前删除所有应该删除的声明性控件(在ASPX文件中定义),无论是在InitComplete事件中还是在它之前的任何其他事件中

    太好了!谢谢你的解决办法。现在我只想知道为什么会这样。为什么它在Page_PreInit事件中工作而不在Page_Load事件中工作?我需要这些信息来接受答案,因为这是我最初的问题。根据ASP.Net页面事件生命周期上的文档,
    PreInit
    是处理动态控件的地方。除此之外,我同意,我想知道更多的原因。我怀疑这和视图状态有关。可能通过删除控件,视图状态会以某种特定的方式序列化,因此,当它在下一页加载时反序列化为页和子控件属性时,它无法这样做,因为根据视图状态,页包含的控件比它应该包含的多。对这种怀疑有什么想法吗?视图状态序列化如此脆弱吗?是的,我想知道它是否使视图状态无效。太好了!谢谢你的解决办法。现在我只想知道为什么会这样。为什么它在Page_PreInit事件中工作而不在Page_Load事件中工作?我需要这些信息来接受答案,因为这是我最初的问题。根据ASP.Net页面事件生命周期上的文档,
    PreInit
    是处理动态控件的地方。除此之外,我同意,我想知道更多的原因。我怀疑这和视图状态有关。也许通过删除控件,视图状态会以某种特定的方式序列化,因此