This is probably the biggest noob question ever but I'm confused as to why my private variables, when they are set in one method, gets reset in another. I have something like this in my code:
namespace Project.Messages
{
public partial class Inbox : System.Web.UI.Page
{
private static int selectedIndex;
private static string messageIDString;
private static int messageID;
//select message to view
protected void viewMessage(object sender, GridViewCommandEventArgs e)
{
//get index
selectedIndex = MsgInbox.SelectedIndex;
if (int.TryParse(e.CommandArgument.ToString(), out selectedIndex))
{
//get selected dataKey, convert to a int
messageIDString = MsgInbox.DataKeys[selectedIndex].Value.ToString();
messageID = Convert.ToInt16(messageIDString);
}
}
//select message to delete
protected void delBTN_Click(object sender, EventArgs e)
{
SqlCommand com = new SqlCommand("DELETE FROM Messages WHERE MessageID = #param1", conn);
conn.Open();
com.Parameters.AddWithValue("param1", messageID);
}
So if I click a message, messageID will be set and the message will be displayed. When I click to delete message after that though, it looks like the variable is resetting/is not the same value as previously set. Do I need to use a static variable or something to achieve this?
Thanks
That is the behaviour. When there is postback, all variables are reset and reassigned. You can use session or viewstate or store the value in a control on the page which is already part of the viewstate e.g. in an hidden field
public int messageID
{
get
{
int retVal = 0;
if(ViewState["messageID"] != null)
Int32.TryParse(ViewState["messageID"].ToString(), out retVal);
return retVal;
}
set { ViewState["messageID"] = value; }
}
It's because of ASP.NET, not C#. You need to save your variables in viewstate. See: variable initialized in class loses its previous value with the page loading
It is because the web is stateless. Here are some methods for passing data between pages.
ASP.net MVC:
http://msdn.microsoft.com/en-us/library/dd394711(v=vs.100).aspx
ASP.net Webforms
http://msdn.microsoft.com/en-us/library/6c3yckfw(v=VS.100).aspx
Hope this helps.
You can also use Session object to store information that you need between requests.
Eg: Session["messageIdString"]=value
For more info : http://msdn.microsoft.com/en-us/library/ms178581(v=vs.100).aspx
Related
Is there any way I can reference a GridView object as a variable within my code behind page so I can refer to it once rather than multiple times?
I'm trying to make my code easier for me to update, and easier to transport. The less references I have to use the better!
This is an example of how my code sort of looks at the moment, there must be a better way of declaring the var GridView_ variable outside of the scope of each void?
public class GlobalVars
{
// Button Toggle
public static bool boolToggleView = false;
// Column Indexes
public static int Column1Index = new int();
}
protected void GetColumnIndexes()
{
// GridView Variable
var GridView_ = GridViewName;
// Column Indexes
GlobalVars.Column1Index = Utility.GetColumnIndexByName(GridView_, "Column1");
}
protected void Button1_Click(object sender, EventArgs e)
{
// GridView Variable
var GridView_ = GridViewName;
if (GlobalVars.boolToggleView)
{
GlobalVars.boolToggleView = false;
}
else
{
GlobalVars.boolToggleView = true;
}
// Bind GridView
GridView_.DataBind();
}
Im trying to set a value in a method as shown below but when i run btnSaveValue there is no value to retrieve. Ive even tried creating a private int val in the defaul class and assigning the value to that but still a blank value comes through - can anyone help me out?
thanks
public partial class _Default : System.Web.UI.Page
{
valueAllocation valAlloc = new valueAllocation();
public void declaringValue()
{
valAlloc.setValue(5);
int testAlloc = valAlloc.getValue();
lblResult.Text="Value set here is:"+testAlloc; //THIS WORKS!!!
}
protected void btnSaveValue_Click(object sender, ImageClickEventArgs e)
{
lblResult.Text = "Value now is:" + valAlloc.getValue(); //DOESNT WORK??????!!!!!
}
}
public class valueAllocation
{
private int val;
public void setValue(int value)
{
val = value;
}
public string getValue()
{
return val;
}
}
This is because you need to save the value in each post using for example the ViewState.
This is a basic problem related with the ASP.Net page life-cycle.
Basically, every time you request your page, a new instance of the page is created on every post, and destroyed when the response returns to the client
If you want to keep the state across post backs, you need to manually save each value in the ViewState
storing the whole type in the ViewState
I think this is your best bet
Custom Type
[Serializable]
public class valueAllocation
{
public int MyValue { get; set; }
}
Code behind
protected valueAllocation MyObject
{
get
{
if(this.ViewState["c"] != null)
return (valueAllocation)this.ViewState["c"];
return null;
}
set
{
this.ViewState["c"] = value;
}
public valueAllocation declaringValue()
{
if (this.MyObject == null)
this.MyObject = new valueAllocation { MyValue = 5 };
lblResult.Text="Value set here is:"+ this.MyObject.MyValue.ToString();
return this.MyObject;
}
protected void btnSaveValue_Click(object sender, ImageClickEventArgs e)
{
declaringValue()
lblResult.Text = "Value now is:" + declaringValue().MyValue.ToString();
}
The problem is you never called decalringValue(), do this
public valueAllocation declaringValue()
{
valAlloc.setValue(5);
int testAlloc = valAlloc.getValue();
lblResult.Text="Value set here is:"+testAlloc; //THIS WORKS!!!
return valAlloc;
}
protected void btnSaveValue_Click(object sender, ImageClickEventArgs e)
{
declaringValue()
lblResult.Text = "Value now is:" + declaringValue().getValue(); //DOESNT WORK??????!!!!!
}
It is because this is web application not a desktop.You have to manage the state of page.Because on web each request is new to server.
for your scenario you have to use "viewstate" technique for maintain the state of your page.
or you have to make your variable static if you want that value is not lose.
for further details googled "State management in asp.net"
Looks like values were not set using valAlloc.setValue(SomeNumber); before calling the below method
Or I would say that valAlloc.val is having a default value of zero
protected void btnSaveValue_Click(object sender, ImageClickEventArgs e)
{
lblResult.Text = "Value now is:" + valAlloc.getValue(); //DOESNT WORK??????!!!!!
}
so you lblResult.Text is getting a zero from valAlloc.getValue()
Looks like you are looking for a static object and static linkage defined. If a global static object works for you in this case, please vote my reply up.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Button click event doesn't work properly
I try to increment an int for each click on a default page. Int=0. It only goes up to 1. What should I do to increment the number for each click?
public partial class _Default : System.Web.UI.Page
{
private int speed = 0;
public int Speed
{
get { return speed; } // Getter
set { speed = value; } // Setter
}
public void accelerate()
{
//speed++;
this.Speed = this.Speed + 1;
}
public void decelerate()
{
// speed--;
this.Speed = this.Speed - 1;
}
public int showspeed()
{
return this.Speed;
}
//car bmw = new car();
public void Page_Load(object sender, EventArgs e)
{
//datatype objectname = new
dashboard.Text = Convert.ToString(this.showspeed());
}
public void acc_Click(object sender, EventArgs e)
{
this.accelerate();
dashboard.Text = Convert.ToString(this.showspeed());
}
public void dec_Click(object sender, EventArgs e)
{
this.decelerate();
this.showspeed();
}
}
You could use the ViewState to maintain the value across postbacks:
private int Speed
{
get
{
if (ViewState["Speed"] == null)
ViewState["Speed"] = 0;
return (int)ViewState["Speed"];
}
set { ViewState["Speed"] = value; }
}
You need to store the result in a way that will persist over postback. I suggest using ViewState, for example:
public int Speed
{
get {
if(ViewState["Speed"] == null) {
ViewState["Speed"] = 1;
}
return Convert.ToInt32(ViewState["Speed"]);
}
set {
ViewState["Speed"] = value;
}
}
Because everytime when you click on the button, it is initializing the value of speed to 0.
HTTP is stateless. That means it wil not retain the values of variable across your postback like you do in Windows Forms programming. So you need to keep the value across your postbacks.
You can use a hidden element in your page to store the value and access the value every time you want to do a function on that:
<asp:HiddenField ID="hdnFileId" runat="server" Value="" />
and in your page load, you can read the value and load it to your variable.
public void Page_Load(object sender, EventArgs e)
{
this.speed = ConvertTo.Int32(hdnFileId.Value);
}
From Adrianftode's comment, the data for the controls like TextBox, Checkbox, Radio button controls values will be posted to the server on the postback because they are rendered as standard HTML form controls in the browser. See Chapter 4. Working with ASP.NET Server Controls.
In my ASP.NET page, I have a generic class that is defined as below:
public partial class log_states : BasePage
{
protected class StatesUsed
{
public int StateCode { get; set; }
public string StateName { get; set; }
}
private List<StatesUsed> _statesUsed;
}
In the Page_Load() event, I initialize _statesUsed like below, and bind it to a grid:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
_statesUsed = new List<StatesUsed>();
BindMyGrid();
}
}
private void BindMyGrid()
{
gvStates.DataSource = _statesUsed;
gvStates.DataBind();
}
I then have a form to add new States. When the user adds a state, I'm trying to add it to the local _statesUsed variable, and rebind the grid. Example:
protected void btnAddState_Click(object sender, EventArgs e)
{
_statesUsed.Add(new StatesUsed { StateCode = 1, StateName = "Test" });
BindMyGrid();
}
This always fails when trying to add the new item saying "Object reference not set to an instance of an object"...
How do I keep _statesUsed persistant? The idea is to add all user input using the generic class and then update the database at one go. If you know of another way to accomplish this, I'd be very grateful.
Thanks in advance!
Instead of
private List<StatesUsed> _statesUsed;
I'm usually using something similar to:
private List<StatesUsed> _statesUsed
{
get
{
var result = ViewState["_stateUsed"] as List<StatesUsed>;
if ( result == null )
{
result = new List<StatesUsed>();
ViewState["_stateUsed"] = result;
}
return result;
}
}
I.e. I am persisting page class variables to the ViewState.
If you want to keep stuff "alive" through multiple postbacks you either have to store stuff to a database, use Session, use the Viewstate, or store it temporarily in shared server memory. Which of these you choose is dependent on your use case,
In your case I would probably add an asp:HiddenField runat="server" ID="HiddenFieldUsedStateIDs" in which I wrote the IDs comma separated whenever there is a change and then read the values into the generic list in Page_Load (on every Page_Load, not just !IsPostBack)
This would utilize the Viewstate mechanism in Asp.Net to write the values to the rendered HTML and read it back into the HiddenField's value on each post
Asuuming that your viewstate in not disabled, you could do,
protected void btnAddMat_Click(object sender, EventArgs e)
{
List<StatesUsed> temp = null;
temp = (List<StatesUsed>)gvStates.DataSource;
if(temp != null)
temp.Add(new StatesUsed { StateCode = 1, StateName = "Test" });
gvStates.DataBind();
}
Can I assign a value to a variable (int) and never lose this value inside any scope ?
the problem is I am assigning the value to the variable in some scopes but the variable returns to its default value (zero) in other scopes..
Example :
protected void Button_AddNewCourse_Click(object sender, EventArgs e)
{
ID = 10;
}
so when I am trying to use ID in other functions it falls back to zero
protected void AnotherFunction(object sender, EventArgs e)
{
// Variable ID here is zero
}
At a guess, perhaps you're a newcomer to ASP.NET and haven't figured out why page-level variables don't keep their state between postbacks. Try reading up on Session state and Viewstate
Or for a general overview: ASP.NET State Management Overview
e.g. based on your code example, you could use a Session entry to store the value:
protected void Button_AddNewCourse_Click(object sender, EventArgs e)
{
Session["ID"] = 10;
}
protected void AnotherFunction(object sender, EventArgs e)
{
int tempID = (int)Session["ID"];
}
There's lots of other things you could also do - use Viewstate, for example.
Change the line that looks similar to this (which is probably somewhere):
public int ID { get; set;}
to something like
// keep the value of ID in this page only
public int ID { get { return (int)ViewState["ID"]; } set { ViewState["ID"] = value; } }
or
// keep the value of ID in every page
public int ID { get { return (int)Session["ID"]; } set { Session["ID"] = value; } }
Maybe try using readonly variables?