What is the effect of IsPostBack Condition? - c#

I have a aspx Page where I am using AJAX. like
<asp:UpdatePanel runat="server" ID="upPanelDDLProgram">
<ContentTemplate>
<asp:DropDownList ID="DDLProgram" runat="server" Width="194px" Height="18px" OnSelectedIndexChanged="OnDDLProgramChanged" AutoPostBack="true">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
and my code behind is like
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
//{
// BindProgramDDL();
//}
BindProgramDDL();
}
protected void BindProgramDDL()
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
DDLProgram.DataSource = programEntities;
DDLProgram.DataTextField = "Shortname";
DDLProgram.DataValueField = "Id";
DDLProgram.DataBind();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
protected void OnDDLProgramChanged(object sender, EventArgs e)
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
the If condition is the page load event, is commented out. If I toggle the comment part of the page load event, it works perfect in both cases. My question is why is this heppening?

IsPostBack tells you if it is a second request to the page. The benefit here is if you need to do anything costly, such as a database call to fill a dropdownlist or similar, you can do it when !IsPostback, then use ViewState to retain the values.
To put it specific to your situation
Using:
if (!IsPostBack)
{
BindProgramDDL();
}
Will result in BindProgramDDL being called ONLY on the first time the page is loaded, all AJAX or other user interaction with the page will NOT call BindProgramDDL;
Without that, in place EVERY page load would call the method, un-necessarily hitting the database for the records.

If I am getting you correct .......
DropDown list has data even you are not binding it second time after post back..........its becasuse its server side control and each serverside control has its view state with it thats y its not removing data.
IsPostBack - it true when do the post back by using serverside control like dropdown, checkbox , textbox............When you load page first time this property is false but in subsequent request to same page value of this property is true. you can check msdn document for more detail about it.

It's basically saying are you visiting the page for the first time (not a post back), or has the user clicked on a control (a post back).
Useful for when you only want to run methods once when the page is initially loaded
You're code should probably look like this to achieve best results
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindProgramDDL();
}
}

I suspect that the DropDownList saves the items in the ViewState and then work with them during all subsequesnt requests. That is why your code works even if the editor's DataSource is set only when IsPostBack returns false.

PostBack event appears on every action (ajax too), except of first page load.

Page.IsPostBack
indicates whether the page is being rendered for the first time or is being loaded in response to a postback.
see http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx
Since you've bound your datasource the first time the page was loaded, the data are still in the viewstate and you don't need to update the control (unless the datasource has changed).
Take also into account that, since you're using ajax, you may also want to intercept if there was an 'asynchronous postback'.
See http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/

Related

DropDownList without Autopostback

I need a DropDownlist which can cause SelectedIndexChanged event but do not do post back(do not need page_load event when ddl index changed).
After looking into solutions in Stack here is my code:
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:DropDownList ID="a" runat="server" OnSelectedIndexChanged="a_SelectedIndexChanged">
<asp:ListItem Text="a"></asp:ListItem>
<asp:ListItem Text="b"></asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="a" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
and C# code:
public partial class TestApp : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
txtDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
}
protected void a_SelectedIndexChanged(object sender, EventArgs e)
{
int a = 1;
}
}
But the break point in put in a_SelectedIndexChanged never gets fired. What could be the issue here?
As you see the above is an accpeted answer on stack, then how its not workining:
How DropDownList's SelectedIndexChanged() works without PostBack?
Edit: While the below answer correctly explains that page_load should fire all the times. I still want to know why SelectedIndexChanged never gets fired. So what EventName="SelectedIndexChanged" in the Trigger does?
While a update panel (UP for this post) will "ajax" up, and ONLY post-back that part of the page. (and code behind for that UP can only update controls in that UP?).
The page load even will ALWAYS fire each time.
In fact, page load fires for any button click, post-back, changed event or anything at all.
Thus, as a STANDARD design pattern?
If your page load event loads up a drop down list, listbox, gridview etc.?
Then you ONLY want that code to run on the "real" first page load.
As a result, the last 200+ web pages I have built?
They have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadData();
}
void LoadData()
{
Repeater1.DataSource = General.MyRst("SELECT * from tblHotelsA");
Repeater1.DataBind();
}
So, in above example, I am loading up a "repeater" with some data.
However, REGARDLESS if you using a UP or not?
Your page load code, first time MUST quite much do the above.
If you don't do the above, then simple code that say loads up a dropdown list (combo box) will fire each and every time.
If then if you select a combo box value, then say click a button on the page?
the page load fires first, AND THEN your button code. But, if page load re-loads the combo box, then you lose your selection.
So, update panel or not?
Your page load event fires each and every time - including when you use that UP.
So, even without a UP, it stands to reason you can't really even build a working web page if you page load event EVERY time loads up data and controls, since then any changes to such controls will be "blowen" out, and over written each time.
So, while the UP results in what "appears" to not be a post-back?
it is in fact what we call a partial post-back. And the standard page life cycle does occur, but ONLY the bits and parts in the UP are posted back to the server, and in that case, ,then the code behind of course can only change/modify the controls inside of that UP (quite much the whole idea).
So, while the UP will "eliminate" the browser spinner, and while it KEEP your current scroll position on the page?
Make no mistake here - that partial post-back is in fact a page post-back, but just a smaller one, and one that looks to the user that no post-back occurred.
so, it is fine and dandy to have auto-post back for that dropdown list. (and you do NOT even require a trigger, and I suggest you remove the trigger, and put back in the auto post-back.
So, the UP does not "eliminate" the post-back, but hides this from the end user, and for the most part it can be rather nice, quick, and of course will not refresh the whole page. But, page load still fires each and every time.
So, for your code to work correctly, and only fire on the VERY first time, and what amounts to the "real" first page load?
Then your code has to be this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
txtDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
}
}
Now, if you really don't want any kind of post back?
Then you have to start writing some JavaScript, and start making ajax calls to some web methods.
Now, a ajax call certainly is "less" of a post-back then a UP, which in turn is less of a full page post-back.
If you absolute have a "poor" page design in which a UP can't be used, then yes, you have to start writing and adding client side js code, and thus you can setup a ajax call, and no page post-back will occur. it is quite rare that a UP can't be used, but ajax calls are better, but they also take significantly more time to setup, write and adopt.
However, keep in mind that a ajax call to server code does not have any use of controls on the page. So, you have to return values, and then have your js code update the controls on the page.
So, if a UP can suffice, then that's the least effort. The fantastic part is you don't have to write up and wire up a whole bunch of JavaScript code in place of using that UP.
For sure, a ajax call is best, but that takes more code, more time, and has more moving parts (and requires JavaScript skills on your part). Often this extra effort and time (cost) can't be justified to adopt ajax calls for the page, so a UP is a good middle ground. it is somewhat of a compromise compared to ajax calls, but it boatloads of less work, and thus often a great choice cost and time wise. In other words, in most cases a UP is "good enough".

SelectedValue & SelectedItem From Drop Down List

I am attempting to write the selected values to two separate text boxes named this.txtTextSelected.Text = text; and this.txtValueSelected.Text = value;
My issue is that the values are not written to the two text boxes, and when an option is selected my page refreshes and doesn't actually store the selected value which makes me think
1) Either my HTML for the drop down list is incorrect
2) I have added un-needed syntax for something
But I am scratching my head as to what the real deal is.
This is my HTML for the drop down list
<asp:DropDownList ID="dropdownlist1" CssClass="DropDownLists"
runat="server" Width="90px"
AutoPostBack="true"
OnSelectedIndexChanged="dropdownlist1_SelectedIndexChanged">
</asp:DropDownList>
And this is my C# code behind for the page
protected void dropdownlist1_SelectedIndexChanged(object sender, EventArgs e)
{
string value = dropdownlist1.SelectedValue;
string text = dropdownlist1.SelectedItem.Text;
this.txtValueSelected.Text = value;
this.txtTextSelected.Text = text;
}
EDIT
Will this remedy my problem (basing this off #David comment below)
if (!IsPostBack)
{
BindDropDownList();
}
(In response to comments and the question edit...)
Unlike WinForms, WebForms "form" objects don't persist in memory. Web applications are designed to be inherently stateless. So every request results in re-instantiating the targeted form object, which invokes all of the start-up stuff that happens in a form.
This includes Page_Load.
So any time you click a button or do anything that involves posting the page back to the server, Page_Load (and other initialization events) happen again, before any event handlers or custom logic.
This means that if you're binding your controls in Page_Load, you're going to re-bind them before you try to use them. In WebForms, the standard fix for this is to wrap them in a conditional when binding:
if (!IsPostBack)
{
// bind your controls
}
This will bind the controls when initially loading a page, but not when re-submitting the page's form to the page (posting back).

UpdatePanel.Update() command generates a full Page_load

I have a Update Panel inside a User Control i use on 2 pages in my website
Both pages use the same MasterPage, ScriptManger is declared in the MasterPage.
Both pages call the UC the same way:
<uc:SearchCube runat="server" ID="searchCube" />
in the Update panel i have many RadioButtons that on change generate a server side event that fill dropdown in the update panel and update the panel
protected void SearchCategoryChanged(object sender, EventArgs e)
{
FillDropdowns();
SearchOptions.Update();
}
Update Panel is set like this:
<asp:UpdatePanel ID="SearchOptions" runat="server" UpdateMode="Conditional"
hildrenAsTriggers="true"/>
Each RadioButton is set like this:
<asp:RadioButton ID="RadioButton1" GroupName="SearchCategory" runat="server"
AutoPostBack="true" OnCheckedChanged="SearchCategoryChanged" Text="Text"/>
I also have an AsyncPostBackTrigger on each Radio Button Controller
The problem i have is that on one page when i call the Update() function the panel is updated and Page_Load is triggered which causes the UC to refresh and reload the default settings of the UC
I can see in DEBUG mode that on the working page Update() does not generate Page_Load.
Can anyone explain to me why this is happening?
Everytime a request goes to the server, it executes the Page_Load event.
What you need to do is make sure you have a PostBack validation on all your pages:
protectec void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//Not a postBack: Normal page load
//Init your page here
}
else
{
//It's a PostBack (from a command).
//Do nothing or init stuff your all your commands.
}
}
If you put some breakpoints in your Page Load and your SearchCategoryChanged method, you'll be able to see what the pipeline looks like.
Fixed my problem.
the problematic page is an index page that takes a few parameters in.
I have a Response.Redirect() on the page to avoid duplication of pages.
Apparently when the PostBack() is made it calls the page without any parameters and i was forcing it to be redirected into a default view since no parameters were sent to the page.
i found a lead to my problem in a Microsoft help forum that stated:
By calling Response.Write() directly you are bypassing the normal
rendering mechanism of ASP.NET controls. The bits you write are going
straight out to the client without further processing (well,
mostly...). This means that UpdatePanel can't encode the data in its
special format.
Anyway the page was reloading every time which caused it to reload the User Control with it's default values.

DropDownList not posting back, even with AutoPostBack set

Obscure solution at end of post
Using asp.net page with C# codebehind, I have successfully built and populated a DropDownList.
What I would like to do is capture a new value selected from the dropdownlist (preferrably using a postback to my codebehind). The codebehind can then update other things on the page based on this newly selected dropdownlist value.
My first attempt was to use
<asp:DropDownList ID="myDDL" runat="server" AutoPostBack="true" OnSelectedIndexChanged="foo"></asp:DropDownList>
with the C# method
public void foo(object sender, EventArgs e)
{
DropDownList ddl = sender as DropDownList;
string myValue = "";
if (ddl != null)
{
myValue = ddl.SelectedValue;
// Do some stuff
}
}
This did not work. When the selected index was changed, it simply reloaded the page, but the IsPostBack flag was always false.
So I sifted through SO and tried a number of different tactics. Most recently, I tried to register the client-side onChange event in the codebehind and turned off the AutoPostBack.
in the ASP.Net page:
<asp:DropDownList ID="myDDL" runat="server" AutoPostBack="false"></asp:DropDownList>
in the codebehind:
myDDL.Attributes.Add("onChange", "doSomeStuff(this);"); // Done on databind.
I added the client-side javascript to call the page's __doPostBack function
<script language="javascript" type="text/javascript">
function doSomeStuff(ddl) {
var ddlVals = document.getElementById(ddl.id);
__doPostBack(ddlVals, '');
}
</script>
This also failed, although I thought it was going somewhere when I saw the javascript execute properly.
Looking in the codebehind, though, it's still not working. When I put a breakpoint in the Page_Load IsPostBack is false! But it's supposed to be a postback!? It was posted back using __doPostBack and (seperately) automatically with AutoPostBack="true"
So I dug deeper.
According to this MSDN article (http://msdn.microsoft.com/en-us/library/ms178141(v=VS.85).aspx) based on the results on the page load I'm doing a "Server Transfer" rather than the desired Postback (IsPostBack is false, PreviousPage is, as expected, the same page that should be posting back, IsCallback is false, and IsCrossPagePosting is false).
What could be going on to hyjack the AutoPostBack and the __doPostBack to make it look and act like a "Server Transfer"?
What can I set/check on the parent control/page to make sure it's allowing postbacks?
EDIT:
The Page_Load looks something like:
private SpecialDataObject _someData;
private string foobar;
public void Page_Load(object sender, EventArgs e)
{
//set some variables.
this.foobar = "blah";
LoadSomeUnrelatedData();
if (!IsPostBack)
{
if (_someData == null)
{
LoadDataWithoutBinding();
}
BindMyData();
}
}
With a breakpoint at //set some variables the Page.IsPostBack is always false even after AutoPostBack.
EDIT 2:
The answer was in the Server Transfer. In a distant control loaded from the master page, the URL is inspected and rerouted before it hits the page, effectively negating my postback. I didn't see it before because I had added the breakpoints only in the target page.
I would check to make sure that you don't have validation somewhere interfering with the postback. To check this, set CausesValidation to false on the DropDownList.
Are you resetting the value of your dropdown in your PageLoad?
Also you may want to think about using an UpdatePanel so that it doesnt reload the whole page.
Is it inside an UpdatePanel? If yes, set ChildrenAsTriggers="true"
Based on the attempts you've mentioned, as well as the comments regarding the update panel, I attempted a few things.
By setting the data source on the load event, you will only do it once:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//set up data here
}
}
You may use the Page.IsPostBack code and the method of yours to get what you want:
if (Page.IsPostBack)
{
//do page reload logic in here
}
protected void foo(object sender, EventArgs e)
{
//get your selected value here
}
(Note: Both of the postback conditionals are in the page load event)
EDIT:
Here's the whole setup, its basic, but you get the idea:
As you can see when I made a selection from cat to dog, it recognized that there was a postback, so it skipped the databind and set t. I could only assume there's something else here that I'm not seeing if you can't get it to ever return true for you on postback.

UpdatePanel reloads the whole page

I'm building an asp.net cutom control inside which I have two dropdownlists: companyIdSelection and productFamilySelection.I populate the companyIdSelection at Page_Load and in order to populate the productFamilySelection depending on the selected item in companyIdSelection.I'm using UpdatePanels to achieve this, but for some reason every time I update companyIdSelection Page_Load is being called ( which as far as I know should happen only when the entire page is reloaded ), the list is being reloaded again and the item the user selected is lost( the selected item is always the top one ).Here's the code
<asp:UpdatePanel ID="updateFamilies"
runat="server"
UpdateMode="Always">
<ContentTemplate>
Company ID:<br>
<br></br>
<asp:DropDownList ID="companyIdSelection"
runat="server"
AutoPostBack="True"
OnSelectedIndexChanged="companyIdSelection_SelectedIndexChanged">
</asp:DropDownList>
<br></br>
Product Family:
<br></br>
<asp:DropDownList ID="productFamilySelection" runat="server"
AutoPostBack="True"
onselectedindexchanged="productFamilySelection_SelectedIndexChanged">
</asp:DropDownList>
<br>
</ContentTemplate>
</asp:UpdatePanel>
protected void Page_Load(object sender, EventArgs e)
{
this.companyIdSelection.DataSource = companyIds(); //companyIds returns the object containing the initial data items
this.companyIdSelection.DataBind();
}
protected void companyIdSelection_SelectedIndexChanged(object sender, EventArgs e)
{
// Page_Load is called again for some reason before this method is called, so it
// resets the companyIdSelection
EngDbService s = new EngDbService();
productFamilySelection.DataSource = s.getProductFamilies(companyIdSelection.Text);
productFamilySelection.DataBind();
}
Also, I tried setting the UpdateMode of the UpdatePanel to "Conditional" and adding an asyncpostback trigger
but the result was the same.
What am I doing wrong?
PS:
I fixed the updating problem, by using Page.IsPostBack in the Page_Load method, but I would still want to avoid a full postback if possible
I think you misunderstand how UpdatePanels work. They DO actually do a full page postback, it's just that during the rendering stage they capture only a portion of the output and send it back in the AJAX response so the page can be updated. More info here.
So you will still need to check whether it is a postback in your page_load event and only perform your data load if it isn't one.
The update panel call back will go through the page load on every call back. In face, the pull page lifecycle (minus render and prerender) will occur. Update panels give the appearance of ajax, but your client side code still posts back to the same page - which is the problem you are describing. If you can avoid using Update Panels, I suggest you do so. Use something like jQuery instead. If not, then use this in your Page_Load
if (Page.IsCallback) { } //Do callback specific code here
else { } //Do Postback specific code here
Hope this helps. Good Luck.

Categories