I've just started learning ASP.NET and I'm facing a problem with getting textbox values. I want to do a simple calculator with only 4 basic operations but what happens is that after I click the + sign and click Go, I see that I didn't store the first number at all. Second number is fine though. Here is a sample of my code.
public partial class deafult : System.Web.UI.Page
{
public TextBox output = new TextBox();
public double temp,tempAdd, calc;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
tempAdd = Convert.ToDouble(output.Text);
output.Text = String.Empty;
}
//User enters another number after clicking Add button then clicks Proc
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
}
I debugged and tempAdd is always 0 but I get the number in temp. temp variables and calc is defined public.
You essentially have the problem with all of your variables being re-initialized on load of the page. Unlike winforms, web is stateless.
There are ways of persisting state between refreshes, however. The most obvious choice for your application would be to only go to the server once with the both values and what you want to do with them. ie One button click.
However, for personal edification, it may be worth looking up ViewState. This allows you to store values in an array of sorts and retrieve them even after a refresh.
There are also Session and Application level arrays in ASP.NET that work in similar ways.
Every time you call the page (by events) all your properties is initialized.
Try to do all your logic in one event or store your properties in manager / service / db.
In web (Asp.Net) on every postback properties will get cleared, try to use ViewState or Session variables to hold these values. Refer Asp.Net State Management concepts from MS.
Hope this may help you.
Web controls are State less so you should user session sate to hold the first value then do your stuff...
Ex:-
protected void btnAdd_Click(object sender, EventArgs e)
{
Session["tempAdd"] = output.Text;
output.Text = String.Empty;
}
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
string oldval=Session["tempAdd"] != null ?Session["tempAdd"].ToString() :"";
if(oldval!="")
tempadd=Convert.ToDouble(oldval);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
Related
I'm new to C# and visual studio, I started learning recently...at the moment I'm trying to make one button that counts the number of clicks and a text box which you can type in any number and it will be reflected in the button counter while adding 1, right now it works but I want the button to add 1 every time you click, here is my code,
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MainWeb1
{
public partial class ButtonCounter : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Text = (TextBox1.Text);
btn.Text = (Int32.Parse(btn.Text) + 1 ) .ToString();
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
string var;
var = TextBox1.Text;
}
}
}
You need to separate the counter on the button from the value that you get from the textbox and recalculate the button text using the updated values.
In an ASP.NET, the class instance of a page is recreated whenever an event happens that requires a callback to the server. You can see this behavior easily if you put a breakpoint inside the page constructor.
So you need something that keeps around the state of your counter between each click. There are many possibilities, hidden fields, static variables or session variables.
A possible approach using a static variable:
public partial class ButtonCounter : System.Web.UI.Page
{
// keeps the count of the clicks on the button
private static int btnCounter;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
btnCounter++;
Button btn = (Button)sender;
btn.Text = (Int32.Parse(TextBox1.Text) + btnCounter ) .ToString();
}
But static variables have some troublesome aspects in ASP.NET apps. They are shared between all users, so a new user will see the counter value reached from the clicks from another user. If, for any reason, the IIS server needs to recycle the application pool, the static variables are lost and they restart from 0.
The Session instead is a memory area assigned to the current user where one can store values or references to information that needs to be kept around until the session ends. So a solution through a Session variable could be
protected void Button1_Click(object sender, EventArgs e)
{
int btnCounter = 0;
if(Session["counter"] != null)
counter = Int32.Parse(Session["counter"]);
counter++;
Session["counter"] = btnCounter;
Button btn = (Button)sender;
btn.Text = (Int32.Parse(TextBox1.Text) + btnCounter ) .ToString();
}
A simpler solution is through the use of an HiddenField control where you keep the counter and use it more or less like the Session example above.
protected void Button1_Click(object sender, EventArgs e)
{
int btnCounter = Int32.Parse(hiddenCounter.Text);
btnCounter++;
hiddenCounter.Text = btnCounter.ToString();
Button btn = (Button)sender;
btn.Text = (Int32.Parse(TextBox1.Text) + btnCounter ) .ToString();
}
This will work because ASP.NET keeps a ViewState for all the controls in your page reinitializing them with the previous values (and this is not so good as it seems because it augments the information that needs to be exchanged between the server and the client)
If you really still want to work with ASP.NET it is of uttermost importance to understand the ASP.NET Page Life cycle but remember that this is an obsolete technology for Microsoft. All the new enhancements are in the realm of ASP.NET Core and the new programming models like ASP.NET MVC and ASP.NET Razor pages.
My session key is a const string variable. See below.
On first Page Load, I add a string to the session using this key. I also indicate to KeepAlive on the key on the first load and every PostBack. However, on PostBack, I notice that the key is no longer in the session.
I found that to fix this, I simply have to remove "const" from the variable, and everything works fine.
Can someone explain and provide any educational resources on why this is happening.
private const string ENTITY_KEY = "c335a928-72ac-4403-b5f8-418f1e5ac1ec";
public string CurrentEntity
{
get { WebClientSession.Current[ENTITY_KEY] as string); }
set { WebClientSession.Current.AddTransient(ENTITY_KEY, value); }
}
protected void Page_Load(object sender, System.EventArgs e)
{
string key = (string)Request["Id"] + "";
CurrentEntity = Mapper.Lookup.FindById(key);
WebClientSession.Current.KeepAlive(ENTITY_KEY);
}
private void _bindGrid()
{
...
// CurrentEntity is null here on PostBack. Good on first load.
...
}
I am not sure what WebClientSession is but the HttpSessionState will work with const. There is no reason why it should not work. Here is the proof that it will work:
private const string ENTITY_KEY = "c335a928-72ac-4403-b5f8-418f1e5ac1ec";
protected void Page_Load(object sender, EventArgs e) {
if( !this.IsPostBack ) {
Session.Add( "ENTITY_KEY", ENTITY_KEY );
}
}
protected void Button1_Click(object sender, EventArgs e) {
string s = Session[ "ENTITY_KEY" ].ToString();
}
I simply added a button to my form. In the load method if the page is being requested I added a const variable's contents to the Session. In the click handler of the button, which is the form being posted, I access it from the Session and it is there.
So why is it not working for you?
There are 2 possible reasons:
Reason 1
The issue is in your WebClientSession class. I do not know the details of that class so cannot say what the issue is.
Reason 2
Session is stored in memory on the server. So, if this site is deployed on a farm, it is possible that the server which served the page initially added the ENTITY_KEY to Session. But when the page is posted back on the button click, another server serves the request. This server may not have the ENTITY_KEY in its memory since it is possible it has never served that page yet. In a web farm, you would want to use another source to store session related data such as a database or a file etc.
Whenever i click on the Button1 repeatedly then text in the Literal1 is not incremented. Can you please tell me reason?
Expected: value show in text field increment after every button click.
Current result: value always shows 1.
public partial class d1 : System.Web.UI.Page
{
int c;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
c = 1;
Literal1.Text = c.ToString();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
c=c+1;
Literal1.Text = c.ToString();
}
}
The reason is that c is an instance variable on that class. And each post-back to the server creates a new instance of the class. So c is being initialized to 0 on each post-back. If you want c to persist outside of a single instance of that class, you need to store it somewhere. Session, application, a database, etc. (Specifically where depends on under what circumstances the value of c should persist. I'm guessing this is just test code to get a feel for the functionality, so you might try all of the above and see how they differ.)
For a lot more information on this, you'll want to read up on the ASP.NET Page Life Cycle.
Essentially, "global" doesn't describe c very accurately as a variable. It's scope is very limited to only that class, and more specifically only to any one instance of that class.
I have intialized some session variables in page load method to zero. Then I am modifying them in button press method. I am using one session variable as a counter but when I am redirecting the page to the same page, the variables are intialized again. Please help me to prevent this re-initialization. I don't want to use static variables.
The scenario is-
protected void Page_Load(object sender, EventArgs e)
{
session["counter"] = 0;
}
protected void Button1_Click(object sender, EventArgs e)
{
int count = (int)session["counter"];
count++;
session["counter"] = count;
response.redirect("same page");
}
Assuming you just want to check for a non set session variable and if so, set it to zero, then you could just do:
protected void Page_Load(object sender, EventArgs e)
{
if(session["counter"] == null) {
session["counter"] = 0;
}
}
There are also a range of client side options you could use, depending on the situation.
Use
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
session["counter"]=0;
}
protected void Button1_Click(object sender, EventArgs e)
{
int count=(int)session["counter"];
count++;
session["counter"]=count;
//remove response.redirect("same page");
}
Your buuton is server side so your page will postback so you do not need to use response.redirect("same page");
If you are indeed redirecting, and not posting back, just check, on page load, if your initial variable has been set? If not, set it. If it is set, ignore setting it.
'set initial value
if session("counter") is nothing then
session("counter") = 0
end if
If you are posting back, you could also use the above, or you could:
If not isPostBack then
session("counter") = 0
end if
You can move that initialisation to a different page. Instead of directly jumping to your "same page" from another part of your application, julp to an "initializer" instead. That page initializes your session variables and immediately redirects to your "same page".
Your "Button_Click" still redirects to "same page", bypassing that initialisation.
In Visual studios, is the class recalled every time the page refreshes? I have the following class - I want to add value to a variable every time a button is clicked;
public partial class _Default : System.Web.UI.Page
{
Random random = new Random();
int total;
int playerTotalValue;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ranPlayer_Click(object sender, EventArgs e)
{
int randomNumTwo = random.Next(1, 10);
playerTotalValue = playerTotalValue + randomNumTwo; //playerTotalValue gets reset to zero on every click
playerTotal.Text = playerTotalValue.ToString();
}
}
playerTotalValue gets resets to zero every time I click 'ranPlayer' button, or this is what I think happens.
HTTP is stateless. That means it will not retain the values in the variable like you do in windows form programming. So whenever you click on the button it executes the same way as it loaded in the initial page loading. But wait !. You have the value available in the text box. So you can read the value from there and store it in the variable.
protected void ranPlayer_Click(object sender, EventArgs e)
{
playerTotalValue =0;
if(!String.IsNullOrEmpty(playerTotal.Text))
{
playerTotalValue =Convert.ToInt32(playerTotal.Text);
}
int randomNumTwo = random.Next(1, 10);
playerTotalValue = playerTotalValue + randomNumTwo; //playerTotalValue gets reset to zero on every click
playerTotal.Text = playerTotalValue.ToString();
}
The duration of this instance is the request. After that it is discarded. Every request will use separate objects.
Any state you need to preserve between requests must be either part of the request (for example an http form field or cookie), or held at the server (session-state).
So yes: playerTotalValue is 0 at the start of each request.
I would create a property that will be storing the value in a ViewState so the value will be preserved on postbacks.