【问题标题】:Maintaining session state in ASP.NET 3.5 using C# with boolean使用带有布尔值的 C# 在 ASP.NET 3.5 中维护会话状态
【发布时间】:2026-01-22 08:05:02
【问题描述】:

我在我的程序类中声明了一些布尔变量并设置为 false。在另一种方法中,我将布尔变量的值更改为 true,但随后我必须通过单击另一个或两个按钮来刷新页面。刷新 ASP.NET 页面后,当我希望它为 true 时,该值将返回 false。如何防止它将布尔变量更改为原始值并将其保持为真。这将是什么 C# 语法。例如,我有以下内容:

public partial class _Default : System.Web.UI.Page
{
    bool plus = false;
    bool minus = false;
    bool multiply = false;
    bool divide = false;
    bool equal = false;
}

在我的程序中进一步向下:

protected void btnMultiply_Click(object sender, EventArgs e)
{
    if (TextBox1.Text == "")
    {
        return;
    }
    else
    {
        multiply = true;
        Session["Tag"] = TextBox1.Text;
        TextBox1.Text = "";
    }
}

按下上面的“乘法”按钮后,我接下来按下等于按钮,如下所示,我的页面刷新,将布尔乘法的值更改回 false:

protected void btnEquals_Click(object sender, EventArgs e)
{
    equal = true;

    if (plus)    
    {     
        decimal dec = Convert.ToDecimal(Session["Tag"]) + Convert.ToDecimal(TextBox1.Text);
        TextBox1.Text = dec.ToString();
    }    
    else if (minus)
    {    
        decimal dec = Convert.ToDecimal(Session["Tag"]) - Convert.ToDecimal(TextBox1.Text);    
        TextBox1.Text = dec.ToString();    
    }    
    else if (multiply)
    {    
        decimal dec = Convert.ToDecimal(Session["Tag"]) * Convert.ToDecimal(TextBox1.Text);    
        TextBox1.Text = dec.ToString();    
    }    
    else if (divide)    
    {    
        decimal dec = Convert.ToDecimal(Session["Tag"]) / Convert.ToDecimal(TextBox1.Text);    
        TextBox1.Text = dec.ToString();    
    }    
    return;    
}

因此,当它计算 (multiply) 时,它会跳过它,因为当它应该为真并计算表达式时它被重置为 false。我的主要问题是如何保持变量为真而不是恢复为假并跳过(乘)?

【问题讨论】:

  • 对于这样的事情,ViewState 绝对比 Session 更好。如果用户单击“返回”,或者在同一页面上打开了多个选项卡,Session 将尝试对所有选项卡使用相同的状态,而 ViewState 将跟踪用户正在查看的特定页面加载的状态当他们点击按钮时。

标签: c# asp.net .net-3.5


【解决方案1】:

这是 asp.net 应用程序的典型情况。关于 Web 应用程序,首先要记住的是它是无状态的。这意味着 2 个连续的请求对彼此一无所知。第一次单击乘法时,乘法标志设置为真。当你点击 equals 时,它被认为是一个新的请求,所以它不知道乘法标志被设置为 true。

当 IIS 服务器接收到一个 http 请求时,它会经过一系列对象(httpApplication、httpruntime、httpmodule、httphandler)。页面对象是为每个请求创建的,并在运行时准备好呈现 html 时释放。因此,在早期请求中设置的任何变量都不会在后续请求中保持其值。

我会建议你在asp.net的上下文中遍历页面生命周期和http请求的生命周期。

要回答您的问题,最简单的解决方案是在会话中保留乘法标志,并在单击等于时使用它。

protected void btnMultiply_Click(object sender, EventArgs e)
{
    if (TextBox1.Text == "")
    {
        return;
    }
    else
    {
        multiply = true;
        Session["multiply"] = multiply
        Session["Tag"] = TextBox1.Text;
        TextBox1.Text = "";
    }
}

protected void Equals_click(...)
{       
   //This is not a complete code but just to give you an idea
   bool mul = Session["multiply"] == null ? false : (bool)Session["multiply"];
   ...
   else if (mul)
   ...      
}

【讨论】:

  • 是的,我真的很想知道为什么有人对此也投了反对票。对此投反对票是没有意义的。
【解决方案2】:

我有点不确定这里问的是什么,无论它看起来不是最佳做法,但我会尽力帮助回答具体问题。 当我想将会话中的值绑定到代码中的变量时,设置一个属性,所以

bool MyVal
{
    get
    {
        return Session["MyVal"] as bool? ?? false;;
    }
    set
    {
        Session["MyVal"]=value;
    }
}

现在在我的其余代码中,我只使用 MyVal,并且知道它在会话级别保持不变。 我的代码可能有一些强制转换/null 问题。

【讨论】:

  • 使用 Session["MyVal"] as bool? ?? false;ViewState 我会支持你
【解决方案3】:

这是由于 ASP.NET 的无状态特性。

  1. 页面首次加载时,会创建一个 _Default 实例,并将 multiply 初始化为 false。页面被呈现给浏览器,对 _Default 实例的引用丢失。

  2. 然后用户单击乘法按钮。这会导致回发到服务器。服务器创建 _Default 的新实例,multiply 被初始化为 false。然后btnMultiply_Click 发生并将multiply 设置为true。页面再次呈现给浏览器,对 _Default 实例的引用丢失。

  3. 然后用户单击乘法按钮。这会导致另一个回发到服务器。服务器创建 _Default 的另一个新实例,multiply 被初始化为 false。然后btnEquals_Click 发生并且multiply 仍然是错误的。

ASP.NET 在请求之间维护状态的一种方式是通过 Session 对象。它保留在 _Default 之外并存在于请求之间。

除了将状态保存在页面的成员变量中之外,您还应该将其存储在 Session 中。像Session["action"] = "multiply" 这样的东西,然后在btnEquals_Clickif( Session["action"] == "multiply" 期间检查它。

就个人而言,我会为此使用 ViewState 而不是 Session。不同之处在于 ViewState 只存在于单个页面及其回发中,而 Session 存在于页面之间。您将使用非常相似的语法:ViewState["action"] 而不是Session["action"]。 ViewState 的工作原理是在标记中的隐藏字段中将数据发送到浏览器,然后在回发时将其重新提交回服务器。

【讨论】:

    【解决方案4】:

    声明:

    decimal? Test(bool plus, bool minus, bool multiply, bool divide, decimal value1, decimal value2)
    {
        var dic = new Dictionary<bool, Func<decimal, decimal, decimal>>
        {
            { plus, (d1, d2) => d1 + d2 },
            { minus,(d1, d2) => d1 - d2 },
            { multiply, (d1, d2) => d1 * d2 },
            { divide, (d1, d2) => d1 / d2 }
        };
    
        Func<decimal, decimal, decimal> func;
        return dic.TryGetValue(true, out func) ? func(value1, value2) : default(decimal?);
    }
    

    用法:

    decimal value1 = ViewState["Tag"];
    decimal value2 = Convert.ToDecimal(TextBox1.Text);
    decimal d? = Calculate(
        ViewState["plus"] as bool? : false,
        ViewState["minus"] as bool? : false,
        ViewState["multiply"] as bool? : false,
        ViewState["divide"] as bool? : false,
        value1,
        value2);
    

    我使用ViewState 是因为我认为它比Session 更合适。

    【讨论】: