Best way to persist session variables on listview itemcommand ASP.NET - asp.net

As the itemcommand event fires after most if not all page/control init/load events. what is the best way to persist session variable data that is modified on itemcomment (adding items for example) so that the page can react to the itemcommand using the modified session?

You could catch the postback earlier in the page's lifecycle:
// id of the control
string id = Request.Form["__EVENTTARGET"];
if (!string.IsNullOrEmpty(id) && id.Contains("myControlId"))
{
string argument = Request.Form["__EVENTARGUMENT"];
...
}
but it's neither very elegant nor safe. I would follow the suggestion of Skowronek: to put more logic on PreRender.

Related

ASP.NET Session and Page Life Cycle

Let's say that in an ASP.NET .aspx page I have the Page Load method and another method for a button click event.
In the Page Load method I'm checking if the user is logged in by checking the Session. Whether he is or not, I'm storing the result in a Global Variable.
Boolean isGuest = false;
protected void Page_Load(object sender, EventArgs e) {
if(Session["id"]==null)
isGuest = true;
else
isGuest = false;
}
Let's say 20 minutes have passed, and I don't know if the Session has terminated or not, and then I click a Button, the event goes like this:
protected void Button_Click(object sender, EventArgs e) {
if(isGuest==false)
//do something
else
// do another thing
}
My Question is : When I'm clicking the button, does ASP.NET go through the Page_Load method again (check isGuest again) or it simply executes what's inside the Button_Click method, means, it uses a Boolean isGuest that could be false, but in reality the session is terminated, means it should be true.
Page_Load is triggered always before the control events.
Have a look: ASP.NET Page Life Cycle Overview
Side-note: If you want to do things only on the first load and not on every postback you have to check the IsPostBack property.
You can:
Define your own class with the UserID, and other profile properties;
Add that class to session in the global.asax session started event Session["NameReferingToYourClass"] = new YourClass();
Set a member variable to your session object early in the page life cycle mYourClass = Session["NameReferingToYourClass"] casted if you need to;
Then you can make any changes to your class anywhere in the code your member variable is available;
Save back your class with all the changes into session on the Page.Unload(..){ Session["NameReferingToYourClass"] = mYourClass.
This way you are using your class properties in your code, including UserId, pretty much like a windows application, there will be no mentioning of session anywhere else in your code.

why the size of List in not incrementing

I create dynamically checkboxes all of them with assigned checkedChanged event, which on postback I recreate and everything is working except one thing;
I should save the value of checked checkboxes in a List . But it seems that on each postBack event (every time I check a checkbox) the elements of the list are lost although myche is a global variable of type List ;
lblProba.Text +="in if clause; element count="+ myche.Count.ToString();
gives me 1 every time I check a checkbox
protected void checkChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
if (chk.Checked)
{
myche.Add(chk.InputAttributes["value"].ToString());
lblProba.Text +="in if clause; element count="+ myche.Count.ToString();
}
else
{
lblProba.Text += "enering else;element count:"+myche.Count.ToString();
}
lblProba.Text += "Final length" + myche.Count.ToString();
for (int t = 0; t < myche.Count; t++)
{
Session["chk"]+= myche[t];
}
}
In a web application you can think of every postback as leading to a completely new start of your application. It doesn't remember any state, all the objects are being instantiated as if it's the first time your application is running.
ASP.NET tries to hide this fact by employing things like ViewState etc., but nevertheless your server-side objects don't live beyond a single request/response cycle.
To carry state through multiple requests you could store intermediate values in the Session variable.
You need to check on the lifecycle of ASP.NET pages. Each time you call a page, ASP.NET creates a new instance of the page, loads it with any Viewstate data (if this is a postback) and passes control to your Load event. Once the page sends the response to the browser, the instance is destroyed.
ASP.NET manages ViewState for the statically created controls automatically. You will have to ensure that any data required to rebuild and populate your dynamic controls is saved in the ViewState and used to rebuild them in your Loaded event.
You should store your list e.g. in Session object to avoid losing it on every postback.

Linq data not updating form after postback

In my application, I have a form that users fill out, then gets approved by a manager. I have various types of forms that all use the same process, so the approval buttons are all done via a user control (which includes the functionality to update the data in the database and call the postback).
However, once I click on the "Approve" button (which is in the user control), the form information doesn't update (it still says "unapproved"). A postback is definitely happening, but not sure why the page isn't updating properly.
I can confirm that the change are being made - when I manually reload the page, it gets updated - but not on the post back.
What am I missing here?
My page:
protected void Page_Load(object sender, EventArgs e)
{
int ID;
// ensure that there's an ID set in the query string
if (Int32.TryParse(Request.QueryString["ID"], out ID))
PopulatePage(ID);
else
Response.Redirect("~/Default.aspx");
}
}
protected void PopulatePage(int ID)
{
using (WOLinqClassesDataContext db = new WOLinqClassesDataContext())
{
lblStatus.Text = wo.Workorder.status;
....
}
}
I think that the Page_Load happens before the code in the submit button. To check this just use a couple of breakpoints. So the page loads the old data since the new data are not saved yet.
You should call a method to load the data inside the OnClick method of the Approve button.
After you've submitted the changes to the database, try running db.Refresh(RefreshMode.OverwriteCurrentValues) to force the changes to be reloaded into the data context.

Get UserControl from inside ControlCollection

So i am currently adding a collection of usercontrols to a Panel Collection.
Here is that code
foreach (IssuePoll poll in issuePollList)
{
IssuePollsUC issuePoll = (IssuePollsUC)Page.LoadControl("~/UserControls/IssuePollsUC.ascx");
issuePoll.LoadPoll(poll, false, politician.PoliticianID);
pnlUnFinishedTest.Controls.Add(issuePoll);
}
I am trying to get those usercontrols so i can call a validate method and save method inside each of those controls. Here is the code i am using for that, but it is not working.
foreach (Control control in pnlUnFinishedTest.Controls)
{
IssuePollsUC issuePolls = (IssuePollsUC)control;
issuePolls.SavePollAnswer(appUser.User.PersonID);
}
I get an error message on the convert, it says
"Unable to cast object of type 'System.Web.UI.LiteralControl' to type 'UserControls.IssuePollsUC'"
EDIT: Looks like the problem lies in the fact that a Control cannot be convert into (User Control)
There are other controls in your panel other than your user control i.e. the literal that is causing the cast to fail. Try
foreach (Control control in pnlUnFinishedTest.Controls)
{
IssuePollsUC issuePolls = control as IssuePollsUC;
if(issuePolls != null)
{
issuePolls.SavePollAnswer(appUser.User.PersonID);
}
}
This will make it more type safe.
EDIT
Please note that you must add dynamic controls in the Page_Init event not Page_Load or anywhere else. I suspect your controls aren't even there - adding them not in Page_Init means that that they are not in ViewState and won't be present in any control collection.

Object data source select method returning nothing in code call

I have an ObjectDataSource with the proper SelectMethod and SelectParameters configured. The data source is bound to a grid view which successfully displays the data on page load.
What I need is the ability to rerun the Select method defined by the ObjectDataSource to be stored in a variable and manipulate the items in it. The issue I keep encountering is that calling the .Select() method always returns 0 rows despite it populating the grid view properly.
Is there a reason I can't manually rerun the Select() method on the object data source?
Update 2:
Here is how I setup the ObjectDataSource:
myObjectDataSource.TypeName = typeof(MyDataAccessObject).ToString();
myObjectDataSource.SelectMethod = "GetBy" + stringVariable;
myObjectDataSource.SelectCountMethod = "GetCountBy" + stringVariable;
myObjectDataSource.EnablePaging = true;
Update 1:
I run the Select() on a link button's OnClick event:
protected void LinkButton1_Click(object sender, EventArgs e)
{
SetupDataSource(); // populates the objSource's SelectMethod, SelectParameters and TypeName etc.
var items = objSource.Select();
int count = items.Count(); // returns 0;
}
The ObjectDataSource is setup (SelectMethod and SelectParameters are set) in the Page_Load event.
ObjectDataSource definition:
<asp:ObjectDataSource ID="objSource" runat="server" EnablePaging="True" SortParameterName="sortExpression" ></asp:ObjectDataSource>
GridView definition:
<asp:GridView
ID="myGridView"
runat="server"
DataSourceID="objSource"
AllowPaging="true"
ShowHeader="true"
AutoGenerateColumns="false"
AllowSorting="true"
Width="100%" >
Turns out that underlying data access object's method took pagination into account and was returning .Take(maximumRows) which was always 0.
As a workaround, I programmatically disabled pagination via myObjectDataSource.EnablePaging = false; then created a new function which does not take into account pagination (a new function was required because the ObjectDataSource was looking for a function with specific paremeters).
You don't mention when (in what event you are trying to rebind the to the DataSource)
Short code snippet may help.
If you are in Postback then Gridviews are not re-bound on postback, their rows are pulled back from viewstate. Resetting the gridview's DatasourceID to the object data source ID on page load (or init?) will cause the gridview to be rebound.
I had similar problem before. I think .Select() is implemented using DataReader and once Select has been called once the reader is empty so any subsequent call to .Select or .Count() will return empty result.
Therefore, what you can do is to use .ToList() to store the result in a list and then just keep reusing the list.

Resources