使用带布尔值的C#在ASP.NET 3.5中维护会话状态

时间:2010-12-02 17:39:47

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

我在程序的类中声明了一些布尔变量并设置为false。在另一个方法中,我将布尔变量的值更改为true,但是我必须通过单击另一个或两个按钮来刷新页面。 ASP.NET页面刷新后,当我希望它为true时,该值将返回false。如何防止它将布尔变量更改为原始值并将其保持为true。这将是什么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;    
}

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

4 个答案:

答案 0 :(得分:2)

这是asp.net应用程序的经典情况。关于Web应用程序要记住的第一件事是它是无状态的。这意味着连续2次请求对彼此一无所知。单击乘法时第一次将multiply标志设置为true。单击等于时,它被视为新请求,因此它不知道multiply标志设置为true。

当IIS服务器收到http请求时,它会经历一系列对象(httpApplication,httpruntime,httpmodule,httphandler)。为每个请求创建页面对象,并在运行时准备好呈现html时将其处理掉。因此,先前请求中设置的任何变量都不会在后续请求中保留其值。

我建议您在asp.net的上下文中浏览页面生命周期和http请求的生命周期。

要回答您的问题,最简单的解决方案是在会话中保存multiply标志,并在单击equals时使用它。

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)
   ...      
}

答案 1 :(得分:2)

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

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

现在在我的其余代码中,我只使用MyVal,并且知道它在会话级别持久存在。 我的代码可能有一些cast / null问题。

答案 2 :(得分:2)

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

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

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

  3. 然后用户点击乘法按钮。这会导致另一个回发到服务器。服务器创建另一个_Default的新实例,multiply初始化为false。然后btnEquals_Click发生了,multiply仍然是假的。
  4. ASP.NET在请求之间维护状态的方法之一是通过Session对象。它被保留在_Default之外并且存在于请求之间。

    您应该将它存储在Session中,而不是将状态保存在页面中的成员变量中。像Session["action"] = "multiply"这样的内容,然后在btnEquals_Click期间使用if( Session["action"] == "multiply"进行检查。

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

答案 3 :(得分:0)

声明:

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更合适。