C# 将ViewState/IPostback与持久化文本框值混淆

C# 将ViewState/IPostback与持久化文本框值混淆,c#,asp.net,textbox,webforms,C#,Asp.net,Textbox,Webforms,场景1: 我创建了一个文本框,按钮,将它们添加到页面中,并在页面的OnInit或OnLoad事件中设置文本框的值 当我进行回发/表单发布时,通过按钮单击,我在文本框(从浏览器)中输入的任何内容都将保留到下一次回发/页面加载 场景2: 我创建了一个文本框和按钮,并将它们添加到OnInit事件的页面中。 我在OnLoad事件上设置TextBox值 当我执行回发/表单发布时,通过按钮单击,我在文本框(从浏览器)中输入的任何内容都不会持久化,而是显示我在OnLoad事件中分配的值 有人能解释一下这里发生

场景1: 我创建了一个
文本框
按钮
,将它们添加到页面中,并在
页面
OnInit
OnLoad
事件中设置
文本框
的值

当我进行回发/表单发布时,通过
按钮
单击,我在
文本框
(从浏览器)中输入的任何内容都将保留到下一次回发/页面加载

场景2: 我创建了一个
文本框
按钮
,并将它们添加到
OnInit
事件的页面中。 我在
OnLoad
事件上设置
TextBox

当我执行回发/表单发布时,通过
按钮
单击,我在
文本框
(从浏览器)中输入的任何内容都不会持久化,而是显示我在
OnLoad
事件中分配的值

有人能解释一下这里发生了什么吗?
猜测一下,我会说,
ViewState
跟踪只在
TextBox
被添加后的事件中启动,或者在下一个事件中分配后它被标记为“脏”,但这些确实是猜测

视图状态跟踪在InitComplete事件中打开。因此,当您在OnInit上添加控件时,它不会被viewstate跟踪,其中,当您在Page_Load上添加控件时,它会被viewstate跟踪,并且您可以检索文本框的持久值。

加载视图状态发生在Init和Load之间、Init之后和Lod之前

“加载视图状态”阶段仅在页面被发回时发生。在此阶段,从上一次页面访问中保存的视图状态数据将被加载并递归填充到页面的控件层次结构中。正是在这一阶段,视图状态才得到验证

如果要将数据持久化到viewstate,则不能为每篇文章重新绑定数据

If(! IsPostBack)
{
   //Bind here your textbox
}

并使用viewstate持久化

控件的viewstate跟踪在控件的init事件结束时打开。请记住,控件事件发生在页面的

PreInit是您应该在其中添加动态控件的事件,但是Init可以工作,但您可能会看到一些不一致的行为。由于明显的原因,不应使用Load


总是检查!设置控件初始值时返回。

首先,让我们澄清一个常见的误解:
文本框的值在回发过程中保持不变,因为浏览器将该值作为表单数据的一部分发送到每篇文章中,而不是因为该值保存在视图状态查看状态与您看到的行为无关

以下是与此问题相关的页面生命周期阶段:

  • 引发
    Init
    事件
  • 加载已发布的表单数据(第一次尝试)
  • 引发
    加载
    事件
  • 加载已发布的表单数据(第二次尝试)
  • 现在,让我们浏览每个场景,看看当用户更改文本框的值并单击按钮时会发生什么

    场景1a:在OnInit中添加控件并设置文本属性。
  • 引发
    Init
    事件。
    TextBox
    被添加到页面中,其
    Text
    属性被设置为“Hello”
  • 加载已发布的表单数据(第一次尝试)。
    Text
    属性设置为用户输入的值
  • 引发
    加载
    事件。什么也没发生
  • 加载已发布的表单数据(第二次尝试)。由于首次尝试加载
    文本
    属性成功,因此未发生任何操作
  • 最终结果:保留用户输入的值

    场景1b:添加控件并在OnLoad中设置Text属性。
  • 引发
    Init
    事件。什么也没发生
  • 加载已发布的表单数据(第一次尝试)。由于
    文本框
    尚未添加到页面,因此未发生任何操作
  • 引发
    加载
    事件。
    TextBox
    被添加到页面中,其
    Text
    属性被设置为“Hello”
  • 加载已发布的表单数据(第二次尝试)。
    Text
    属性设置为用户输入的值
  • 最终结果:保留用户输入的值

    场景2:在OnInit中添加控件。在OnLoad中设置Text属性。
  • 引发
    Init
    事件。
    文本框将添加到页面中
  • 加载已发布的表单数据(第一次尝试)。
    Text
    属性设置为用户输入的值
  • 引发
    加载
    事件。
    Text
    属性设置为“Hello”
  • 加载已发布的表单数据(第二次尝试)。由于首次尝试加载
    文本
    属性成功,因此未发生任何操作

  • 最终结果:用户输入的值被覆盖。

    查看asp.net中的页面生命周期可能会有所帮助。我假设您正在if(!IsPostback)检查中为OnLoad事件中的文本框赋值?OnInit事件是动态创建控件的正确位置,viewstate在OnInit完成后加载。关于页面生命周期,这里还有一个很好的链接:@DaveZych感谢您的链接。我的问题可能更具体到TextBox。如果文本框值被分配了
    ,则场景2的行为与场景1类似!不管怎样,我都会回邮,但这并不能回答我的问题!我想我不理解你的评论。文本框的值在
    Page_Init
    事件期间从
    Viewstate
    加载。。。当然,它们将被您在
    页面加载期间设置的值覆盖,这是不正确的。在
    Init
    事件期间添加控件是首选,并且绝对会被
    Viewstate
    跟踪。它是首选的,因为除此之外
    private TextBox textBox = new TextBox { ID = "textBox" };
    private Button button = new Button { ID = "submitButton", Text = "Submit" };
    
    protected override void OnInit(EventArgs e)
    {
        this.placeHolder.Controls.Add(this.textBox);
        this.placeHolder.Controls.Add(this.button);
        this.textBox.Text = "Hello";
    }
    
    protected override void OnLoad(EventArgs e)
    {
        this.placeHolder.Controls.Add(this.textBox);
        this.placeHolder.Controls.Add(this.button);
        this.textBox.Text = "Hello";
    }
    
    protected override void OnInit(EventArgs e)
    {
        this.placeHolder.Controls.Add(this.textBox);
        this.placeHolder.Controls.Add(this.button);
    }
    
    protected override void OnLoad(EventArgs e)
    {
        this.textBox.Text = "Hello";
    }