Timer in UpdatePanel causes some sort of full postback - c#

I have some sort of a strange problem, I have an update panel which is triggerd by a timer.
Also I have on this page is a function that calls the DB and retrieves data from it. the function does not being called from the update panel or even related to it.
the problem is that I see in my log file that every time there is a tick and the update panel being updated there is also a call to my DB server (this function is in the page_Load section ) to retrieve the data again. but the page doesn't seem to do a full postback (It stays the same and doesn't looks like being reloaded)
my code:
<asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
</Triggers>
<ContentTemplate>
<span id="s1" runat="server"></span>
</ContentTemplate>
</asp:UpdatePanel>
and code behind:
protected void UpdateTimer_Tick(object sender, EventArgs e)
{
DateTime dt = TimeConvertor.getCurrentGameTime();
s1.InnerText = String.Format("Current game time: {0:dd/MM/yyyy HH:mm}", dt);
}
The function to retrieve data from the DB is in the page_load of the page.
Any help is appreciated
Thank you
Doron

Using the Update panel doesn't refresh whole page, only controls inside update panel, but when Partial Update is executed all the server page life-cycle events occur, and view-state and form data are preserved, but when rendering page only part of update panel is rendered and returned to user.
Go to this link Partial page rendering
and scroll to the section background.

Related

UpdatePanel with AsyncPostback tryes to update control outside UpdatePanel

I need to have UpdatePanel with asyncpostback, but in my case it seems that no partial postback happens, but fullpostback. I am new to web forms, please, check the code:
<%# Register TagPrefix="Cust" TagName="CompanyInformationView" Src="~/CustomControls/CompanyInformationView.ascx" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<asp:UpdatePanel runat="server" ID="UpdatePanel1" ChildrenAsTriggers="true" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" OnClick= "Button1_Click" Text="test" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<Cust:CompanyInformationView ID="CompanyInformationView" runat="server" />
</asp:Content>
So I have Test Button. OnClick it should do "nothing" for test. Also there is custom control on web form. Here is server side code for this form:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// fill in custom control
CompanyInfo c = GetInfo();
CompanyInformationView.Company = c;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
var i = 1;
}
CompanyInformationView is custom control with property "Company". There is no ViewState added for this property (so it cannot be loaded properly if postback is done). When I click on Test Button, the page fails, because "CompanyInformationView.Company" is not set (it is not set, because it cannot be loaded from ViewState, I guess).
Instead, I think that it should not work like this. AsynPostback should deal only with UpdatePanel.
Why it wants to reload custom control? Doesn't it mean that Full postback happen or maybe I do not understand Asyncpostback?
PageLoad and all other events are raised on every get\postback, no matter if it's async or full,
In asyncpostback, the response which the server renders includes only the content inside the updatepanel.
Try to Put <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
Before
<asp:UpdatePanel runat="server" ID="UpdatePanel1" ChildrenAsTriggers="true" UpdateMode="Conditional">
Async post back in web forms still proceeds the whole page life cycle as if it's a traditional post. the difference is only the updated content inside target update panel that will be sent in response. so in this case, async post back will still give you exception unless you populate the custom control no matter get/post.
you need to also put the custom control inside another update panel or in the same update panel as the button in order see partial update to happen.

Update an update panel within loop ASP.Net Web Forms C#

I have been trying to find a way to relay incremental feedback of a process to the UI via an update panel. A basic example of what I am trying to implement is as follows:
protected void DoSomething(object sender, EventArgs e) {
for(int i=0; i < 10; i++){
//Pretend to do something intensive
Thread.Sleep(1000);
//Output the progress of the process to a label
Label.Text = i.ToString();
}
}
The aspx markup in my example is simply:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
<asp:Button ID="Button1" runat="server" OnClick="DoSomething" Text="Push Me"/>
However when Button1 is pressed the UpdatePanel does not update incrementally, instead it only displays the number 9 when the loop completes.
I believe this is because no postback is triggered until the server side code completes (i.e. when the loop stops looping).
Is there a way I can achieve the desired functionality using server side code and update panels?
Thanks in advance! :)
What you can do is, create a timer object in design mode (or punch it in your html code) and also add a async trigger to that timer. This link will help you a great deal!
http://msdn.microsoft.com/en-us/library/vstudio/bb386404(v=vs.100).aspx
In other words, the timer will trigger update in panel in that time interval you set up :)
In code behind, every timed event,y ou update your update panel w/ incremental value.

JScript runtime error when using UpdatePanel

I am trying to create a dynamic UI using UpdatePanel of AJAX toolkit.
Let me explain the context of my application a bit. There are many profiles. Each profile has a number of product classes. Each product class has a number of products.
I am implementing a comparison of products.
Profiles are represented by RadioButtonList (dynamically created). For each product class of selected profile a DropDownList need to
be dynamically created that allows user to select a product of that class.
Everything is working fine on the first selection. However when I try to select another product and click submit the second time, the following error is thrown:
Microsoft JScript runtime error:
Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback
or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page.
Any hints on why this error is thrown would be very helpful.
protected void Page_Load(object sender, EventArgs e)
{
pnlDynamic.Visible = false;
if (!this.IsPostBack)
{
LoadProfiles(); //Data binding is done for radio button list
}
else
{
btnSubmit.Enabled = true;
GenerateProductUI(ProfileID); //DropDownLists are dynamically created and populated from database
//ProfileID is the selected profile id
}
}
<asp:UpdatePanel runat="server" id="UpdatePanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="rblProfiles" eventname="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server">
<asp:RadioButtonList ID="rblProfiles" runat="server" AutoPostBack="True"
onselectedindexchanged="rblProfiles_SelectedIndexChanged">
</asp:RadioButtonList>
</asp:Panel>
<br />
<asp:Panel ID="pnlDynamic" runat="server" Visible="false">
<asp:Panel ID="Panel2" runat="server">
<asp:Table ID="table" runat="server"/> <!-- Product dropdowns generated in table -->
</asp:Panel>
</asp:Panel>
<br />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" CssClass="btnSubmit" AutoPostBack="True" />
<asp:UpdatePanel runat="server" id="UpdatePanel1" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="btnSubmit" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="pnlResult" runat="server" Visible="false">
<!--Result displayed-->
</asp:Panel>
<br />
</ContentTemplate>
</asp:UpdatePanel>
IMPORTANT! EVERYONE WHO EVER DISABLES EVENT VALIDATION SHOULD UNDERSTAND WHAT HE IS DISABLING!
Imagine that you have a blogging application (or a banking application) and there is a list of comments (or bank accounts) all users can see the comments (or the accounts) but only moderators (or managers) can delete them. So you write a check to switch the delete button visible property depending on the access of the user. Users who are not moderators (managers) cannot delete the comment (account). Problem solved.
HOWEVER if you disable event validation a malicious user can send a post request claiming to have pressed the delete button despite the fact that it was never enabled for him. Normally the event validation would kick in and produce an exception but if it is disabled ASP.NET would not check if the button was visible and will just run the button click handler code and the comment (account) would be deleted. This can be prevented if you check if the user can delete in the button click event but you should also consider that another developer may come later and add another button (edit?) without noticing that event validation was disabled. Also now all other buttons on the page require the appropriate checks. Be very careful if you disable event validation!
The error occurs because you are triggering a postback from a control which does not exist when the original page was rendered. One way to fix it would be to disable event validation for this page but you should make sure to check the credentials of the user requesting the change in the event itself otherwise it is a security issue because a user will be able to "press" a button that was not rendered at all (for example on products he does not have access to).
You can disable event validation through the page directive:
<%# Page EnableEventValidation="false" ... %>
I believe it is also possible to set the update mode of the update panel to always instead of conditional which maybe will fix the issue (can you try it and tell us?) but this will increase the data sent over the network. If it is a good trade off depends on your use case, on the number and size of the update panels you have on the page (the more you have the worse). If it is an internal app or this UI is accessed relatively rarely I would go for this approach (assuming it works because I have not validated that).
BTW this is not actually a script error. You are getting a client side script error simply because the error surfaces through an AJAX request. This is purely a server error that is raised because of a potential security issue with your code.
Add <%# Page EnableEventValidation="false" %> at the top of the page.
Once dynamic dropdown lists are created you have to recreate them or any dynamically created control on every page init or page load. In such case you don't need to use EnableEventValidation="false".
protected void Page_Load(object sender, EventArgs e)
{
pnlDynamic.Visible = false;
if (!this.IsPostBack)
{
LoadProfiles(); //Data binding is done for radio button list
}
else
{
btnSubmit.Enabled = true;
}
GenerateProductUI(ProfileID); //DropDownLists are dynamically created and populated from database
//ProfileID is the selected profile id
}
Or just move GenerateProductUI(ProfileID) from Page_Load to Page_Init

Refresh only a specified spot in asp.net website (Updated code) not working

I want to do page load every 5 sec so I have this in my head content
<meta http-equiv="refresh" content="5" />
Because of this the whole page refreshes. I just want to refresh the gridview and the graph that I have in the page. How can I do that without refreshing the whole page.
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" EnablePageMethods="true" EnablePartialRendering="True"
runat="server">
</asp:ToolkitScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<div id="pie">
<canvas width="125" height="450" id="progress1">[No canvas support]</canvas>
<canvas id="pie1" position="relative" width="400" height="400">[No canvas support]</canvas>
</div>
<asp:Panel runat="server" ID="Panel_Users">
<asp:GridView ID="Grid_UserTable" runat="server"
OnRowDataBound="MyGrid_RowDataBound">
<Columns> </Columns>
</asp:GridView>
</asp:Panel>
<asp:Timer ID="TimerClickEvent" runat="server" Interval="4000" ontick="TimerClickEvent_Tick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
protected DateTime LastUpdate
{
get
{
return (DateTime)(ViewState["LastUpdate"] ?? DateTime.Now);
}
set
{
ViewState["LastUpdate"] = value;
}
}
protected void TimerClickEvent_Tick(object sender, EventArgs e)
{
if (LastUpdate.AddSeconds(5.0) < DateTime.Now)
{
UpdatePanel1.Update();
LastUpdate = DateTime.Now;
}
}
protected void Page_Load(object sender, EventArgs e)
{
ToolkitScriptManager1.RegisterAsyncPostBackControl(TimerClickEvent);
if (!IsPostBack)
{
LastUpdate = DateTime.Now;
}}
Doesn't reload. where am I going wrong
Place the panel inside an UpdatePanel and use method updatePanelID.Update() to update the update the Panel containing GridView. See this for more details
Instead of button click event you can use a timer for that.
If you only want to refresh a region, there are 2 options:
load that into an <iframe> and let it do whatever it wants (via meta-refresh on the document inside the <iframe>
reload the implacted region via javascript, perhaps jQuery's .load() method, i.e. $('#id').load(url);
A meta-refresh on the entire page will, by necessity, reload the entire page.
For a built in asp.net solution, use an <asp:UpdatePanel> along with an <asp:Timer> control.
Set the update panel to update based on the Timers Tick event. This will then only update the content within the update panel.
HOWEVER, this is a quick and dirty solution (in my opinion) because even though the content on the page only updates within the update panel, the whole page is actually posted back each time, and anything within the Page_Load method will be processed again.
Another solution would be to use some javascript ajax, and only update what you need to update. A great javascript library which will help you with this is jQuery, and then use the AJAX features of this. This will allow you to reload on the areas that you need, and give you far greater control over what is happening.
I would forget about the AJAX Control Toolkit, and look more into jQuery Ajax and jQuery UI.

How do you use an UpdatePanel properly?

I have an UpdatePanel with some checkboxes in it. I check them, and hit my Save button, but that causes the UpdatePanel to postback (refresh) and sets them all back to blank. The re-drawing method runs before the button code.
What is the correct way to have an UpdatePanel with checkboxes in that you can manipulate?
Example of code:
<asp:UpdatePanel runat="server" UpdateMode="Conditional" ID="updatePanel1">
<ContentTemplate>
<asp:CheckBox runat="server" ID="myCheckBox" Caption="CheckBox"/>
<asp:Button runat="server" ID="saveButton"
Caption="Save" OnClick="SaveButtonClick"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="saveButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Make sure that:
UpdateMode of UpdatePanel is Conditional
SaveButton contained in Triggers-section as ControlID of AsyncPostBackTrigger
Your code behind should look like:
if(!page.ispostback)
{
re-drawing();
}
As when you hit Save button your re-drawing() method is called and it again refreshes your checkboxes. Asynchronous postback behaves and hit to page method the same as full postback, but refreshes the values in any updatepanels.
Also check this URL
http://ajax.net-tutorials.com/controls/updatepanel-control/
Make sure the Save button is inside the Update Panel, for a start, and if not, that is designated as a Trigger for the Update Panel, in the <Triggers> section of the Update Panel.
<asp:UpdatePanel ID="MyControlPanel" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="SaveButton" />
</Triggers>
<ContentTemplate> ...
Can you show some code for your UpdatePanel?
If you use server controls to render checkboxes you should add EnableViewState="true" attribute to these controls and update panel.
If you have checkboxes that are not server controls, then remove them from update panel, include only server controls inside. This leads to keeping several updates panel on a page that's usually not a big issue.
Add a ScriptManager object to your page if you do not have one. Set EnablePartialRendering="true". Put your UpdatePanel anywhere else on the page and place the content you want ajaxified within a tag within your UpdatePanel.

Categories