【问题标题】:How to ignore viewstate of a previous request for particular control?如何忽略对特定控件的先前请求的视图状态?
【发布时间】:2010-06-17 17:18:51
【问题描述】:

我正在动态生成控件,有时我想创建一个控件并让它忽略视图状态。例如,有时用户单击了一个按钮,表示他们想要加载不同的表单,因此我在回发时生成的控件树与原始控件树不同。这很好,除非当我调用 Controls.Add 时,如果控件树结构相似,它会尝试将视图状态从旧控件加载到新控件中,并且我希望它们忽略该视图状态(并且也忽略回发值也适用于输入控件)。

我可以设置控件的 ID 或允许我有条件地阻止它们获取上一个请求的视图状态/回发数据之类的操作吗?

编辑:如果我让控件的用户在回发处理程序中按需加载表单,则在我调用 Controls.Add 时不会应用回发数据(这看起来确实是 ASP.NET 中的一个缺陷,因为我认为如果您要通过 Controls.Add “事后”应用视图状态数据,那么您似乎会在加载视图状态数据后自动应用回发数据)。我遇到的真正问题是我的控件非常动态,但是我的控件的用户在他们的回发处理程序触发之前无法真正告诉它要做什么,因为用户可以做的一件事是选择不同的表单通过一些链接按钮加载。因此,直到回发处理程序运行,他们才知道 uesr 请求了什么,因此可以要求我的控件加载某个表单。所以我必须要求他们做一些重要的事情,比如将标识最后一个表单的 formID 保存到会话变量中,并且在 OnInit 中,他们通过属性告诉我的表单旧的 formID 是什么。然后我的控件在 OnLoad 中加载表单,以便它可以使用视图状态和回发数据,稍后在程序员的回发处理程序中,他们可以选择清除表单并根据需要加载不同的表单。

Edit2:仅供参考,为表单唯一的每个控件生成 ID 效果很好,所以我认为我可以消除对旧表单的无意义加载,直到程序员请求将表单加载到他的回发处理程序中。但正如我上面提到的,我发现在回发数据处理发生后加载表单意味着数据丢失。而视图状态通过 Contorls.Add 加载,在页面生命周期中追赶,似乎回发数据没有!所以看来我动不动就被打败了。

【问题讨论】:

    标签: c# asp.net viewstate


    【解决方案1】:

    如果您使用控件生命周期,您将避免出现问题。基本上,只要您有一个可以呈现的控件,最好确保在下一次回发时重新创建该控件,即使您不再需要它。回发的第一个目标应该是恢复之前的状态——然后你才对其进行更改。

    我在这个答案中描述得最好:

    Wrong state in Server Controls with same ID's when dynamically adding UserControl to UpdatePanel

    【讨论】:

    • Ugghhh 我认为你是对的,没有办法绕过它。
    【解决方案2】:

    为控件提供不同的 ID 肯定会阻止加载 ViewState,这是一种方法。

    您还可以通过将控件的ViewStateMode 属性设置为“禁用”来操作它。我不确定这是否会阻止它加载(它肯定会阻止它们保存视图状态),但您可以尝试一下。

    【讨论】:

    • +1 大家,但我将此标记为答案,因为它直接解决了有关忽略视图状态的问题。此外,即使我无法真正消除旧表单的加载,设置 ID 仍将是我解决方案的一部分,但每当我无法加载旧表单时,这将很重要,因为它不再有效,因此我可以忽略视图状态(长篇大论,我不会进入)。说声谢谢就够了。
    【解决方案3】:

    您是否尝试过在添加新控件之前调用 controls.clear?

    更新

    我开始相信您在页面生命周期的错误点生成控件。你的流程是什么?

    【讨论】:

    • 我确实尝试过,我必须做的解决方法是在回发期间,动态生成以前的表单,以便他们可以使用视图状态/回发,然后调用 Clear,然后创建新形式。如果我在调用 clear 之前没有生成旧表单,则表单中尚不存在控件,因此视图状态仍将等待并应用于新表单,这通常会在控件类型为不同。
    • 我已经尝试了 onload、oninit 的各种组合,以及我控件用户的函数调用(他从回发处理程序调用,如按钮单击),但无论何时调用Controls.Add 然后 asp.net 通过所有已经发生的事件运行您的控件,因此无论如何都会加载视图状态。所以在我的测试中,这两种方式似乎都没有什么不同。
    • 实际上我撒谎是因为如果我在生命周期中添加控件太晚,回发数据会丢失。见编辑。
    【解决方案4】:

    您必须在页面加载的回发中生成动态控件:

        protected void Page_Load(object sender, EventArgs e)
        {
          --Generate Dynamic Controls--
        }
    

    你需要这样做:

        protected override void OnInitComplete(EventArgs e)
        {
            base.OnInitComplete(e);
        }
    
        protected void OnInit()
        {
         --Generate Dynamic Controls--
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      • 2020-07-27
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多