简体   繁体   中英

Maintaining session state in ASP.NET 3.5 using C# with boolean

I have some boolean variables declared in the class of my program and set to false. Within another method, I change the value of the boolean variable to true but then I have to refresh the page by clicking another button or two. Once the ASP.NET page refreshes, the value returns back to false when I want it to be true. How can I prevent it from changing the boolean variable to the original value and keep it as true. What would be the C# syntax for this. For example, I have the following:

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

Down further in the program I have:

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

After I press the above "Multiply" button I next press the equals button as below and my page refreshes changing the value of the boolean multiply back to 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;    
}

So when it evaluates the (multiply), it skips it because it is reset to false when it is supposed to be true and evaluate the expression. My main issue is how to keep the variable true instead of reverting back to false and skipping the (multiply)?

This is a classic situation with asp.net applications. The first thing to remember about a web application is that it is stateless. It means 2 consecutive requests do not know anything about each other. The first time when multiply is clicked the multiply flag is set to true. When you click equals, it is considered a fresh request, so it has no idea that the multiply flag was set to true.

When the IIS Server receives a http request, it goes through series of objects(httpApplication, httpruntime, httpmodule, httphandler). The page object is created for each request and disposed off when the runtime is ready to render the html. Hence any variables set in earlier request do not hold their value in subsequent requests.

I will advise you to go through the page life cycle and the life cycle of a http request in context of asp.net.

To answer your question, the simplest solution is to hold the multiply flag in session and use it when the equals is clicked.

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

I am a little unsure about what is being asked here, and whatever it is does not look like best practices, but I will try to help answering the specific question. When I want to bind a value from a session to a variable in code, is et up a property so

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

now in the rest of my code I just work with MyVal, and know that it is persisted at the session level. My code may have some casting/null issue.

This is due to the stateless nature of ASP.NET.

  1. When the page first loads, an instance of _Default is created and multiply is initialized to false. The page is rendered to the browser and the reference to the _Default instance is lost.

  2. Then the user clicks the multiply button. This causes a postback to the server. The server creates a new instance of _Default and multiply is initialized to false. Then the btnMultiply_Click happens and sets multiply to true. Once again, the page is rendered to the browser and the reference to the _Default instance is lost.

  3. Then the user clicks the multiply button. This causes another postback to the server. The server creates another new instance of _Default and multiply is initialized to false. Then the btnEquals_Click happens and multiply is still false.

One of the ways ASP.NET maintains state between requests is through the Session object. It's kept outside of _Default and lives between requests.

Instead of saving the state in member variables in page, you should store it in Session as well. Something like Session["action"] = "multiply" and then check it during btnEquals_Click with if( Session["action"] == "multiply" .

Personally, I would use ViewState instead of Session for this. The difference is that ViewState only lives on a single page and its postbacks, while Session exists across pages. You'd use a very similar syntax: ViewState["action"] instead of Session["action"] . ViewState works by sending the data to the browser in a hidden field in the markup, which is then resubmitted back to the server on postback.

Declaration:

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?);
}

Usage:

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);

I'm using ViewState because I think it's more suitable rather then Session .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM