You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET按钮点击时类对象无法保留值的问题咨询

ASP.NET中类对象值无法跨回发保留的问题

我用ASP.NET C#编写测试代码,尝试在类对象中存储值,但结果与预期不符。

代码示例

HTML代码

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication10._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">

        <div>
            <table>
                <tr>
                    <td>
                        <asp:Label ID="Label" runat="server" Text="Speak:">
                        </asp:Label><asp:TextBox ID="tbOutput" runat="server"></asp:TextBox>
                    </td>
                    <td>
                        <asp:Button ID="btnAddHello1" runat="server" Text="Hello1" OnClick="btnAddHello1_Click" />
                        <asp:Button ID="btnAddHello2" runat="server" Text="Hello2" OnClick="btnAddHello2_Click" />
                    </td>
                </tr>
            </table>
        </div>
</asp:Content>

C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication10
{
    public partial class _Default : Page
    {
        public class clsPerson
        {
            public string strSpeak = "";
        }
        clsPerson clsPerson1 = new clsPerson();
        protected void Page_Load(object sender, EventArgs e)
        {

          if (!IsPostBack)
          {
                clsPerson1.strSpeak += "Hello";
                Console.WriteLine("strSpeak(NotIsPostBack) = " + clsPerson1.strSpeak);
                tbOutput.Text = clsPerson1.strSpeak;
            }
          else
          {
                clsPerson1.strSpeak += "Hello3";
                Console.WriteLine("strSpeak(IsPostBack) = " + clsPerson1.strSpeak);
                tbOutput.Text = clsPerson1.strSpeak;
            }
        }

        protected void btnAddHello1_Click(object sender, EventArgs e)
        {
            clsPerson1.strSpeak += "+Hello1";
            Console.WriteLine("strSpeak(Hello1 Button) = " + clsPerson1.strSpeak);
            tbOutput.Text = clsPerson1.strSpeak;
        }

        protected void btnAddHello2_Click(object sender, EventArgs e)
        {
            clsPerson1.strSpeak += "+Hello2";
            Console.WriteLine("strSpeak(Hello2 Button) = " + clsPerson1.strSpeak);
            tbOutput.Text = clsPerson1.strSpeak;
        }
    }
}

输出情况

default output is Hello
when press hello1 button, output is "Hello3+Hello1"
when press hello2 button, output is "Hello3+Hello2"

问题原因

ASP.NET基于无状态的HTTP协议,每次触发按钮点击这类回发操作时,服务器都会重新创建_Default页面类的实例,你定义的clsPerson1对象也会被重新初始化,之前存储的值自然会丢失。这就是为什么每次点击按钮后,strSpeak都会从初始空值开始拼接,而非保留上一次的结果。

解决方案

要让类对象的值在回发间保留,有几种常用方案:

1. 使用ViewState

ViewState是ASP.NET内置的状态机制,专门用于同一页面的多次回发间保存数据。使用时需注意:

  • 存储的对象必须标记为可序列化([Serializable])
  • 每次修改对象后要重新存入ViewState

修改后的C#代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication10
{
    public partial class _Default : Page
    {
        [Serializable] // 标记类可序列化
        public class clsPerson
        {
            public string strSpeak = "";
        }

        clsPerson clsPerson1;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                clsPerson1 = new clsPerson();
                clsPerson1.strSpeak += "Hello";
                ViewState["PersonData"] = clsPerson1; // 存入ViewState
                tbOutput.Text = clsPerson1.strSpeak;
            }
            else
            {
                clsPerson1 = (clsPerson)ViewState["PersonData"]; // 从ViewState读取
                clsPerson1.strSpeak += "Hello3";
                ViewState["PersonData"] = clsPerson1; // 重新存入更新后的值
                tbOutput.Text = clsPerson1.strSpeak;
            }
        }

        protected void btnAddHello1_Click(object sender, EventArgs e)
        {
            clsPerson1 = (clsPerson)ViewState["PersonData"];
            clsPerson1.strSpeak += "+Hello1";
            ViewState["PersonData"] = clsPerson1;
            tbOutput.Text = clsPerson1.strSpeak;
        }

        protected void btnAddHello2_Click(object sender, EventArgs e)
        {
            clsPerson1 = (clsPerson)ViewState["PersonData"];
            clsPerson1.strSpeak += "+Hello2";
            ViewState["PersonData"] = clsPerson1;
            tbOutput.Text = clsPerson1.strSpeak;
        }
    }
}

2. 使用Session

如果需要跨多个页面或者在用户会话周期内保留数据,可以使用Session。Session是基于用户会话的状态存储,使用方式和ViewState类似:

// 存入Session
Session["PersonData"] = clsPerson1;
// 读取Session
clsPerson1 = (clsPerson)Session["PersonData"];

3. 使用HiddenField

如果只需要保存字符串这类简单数据,可以用asp:HiddenField控件存储值,回发时直接读取控件的值:

<!-- 在ASPX页面添加隐藏字段 -->
<asp:HiddenField ID="hdnSpeak" runat="server" />
// 存入值
hdnSpeak.Value = clsPerson1.strSpeak;
// 读取值
clsPerson1.strSpeak = hdnSpeak.Value;

内容的提问来源于stack exchange,提问作者jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:13:25