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
相关产品推荐
相关产品推荐

