I have a ASPX Page that contains several user controls, which are loaded dynamically after user interaction.
On one of ascx I have a hidden button that is being clicked on some user actions (via button.click()), which works fine on 1st page load.
But after the form is being submitted once, the other ascx is loaded. There if user clicks the back button and resubmits the 1st form (again via button.click()), button_clicked event on server does not fire again. Any thought?
This is the solution - 2nd one is needed because of FireFox 3, which does preserve NO-CACHE directive.
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Related
I have 2 asp.net web forms. The first has a ScriptManager, History, UpdatePanel and GridView; the later is ScriptManager, UpdatePanel and TextBoxes. The premise here is a list that links to a detail form where an item can be edited.
From within the GridView (inside the UpdatePanel), if I use a HyperLink control with the url set to the edit page (with the necessary parameters), change something, save it and then click the back button I see the original list with no updates. Pressing F5 to refresh shows the changes.
If instead I use a LinkButton inside the GridView, and handle that LinkButton in code-behind to perform a Response.Redirect to the same edit page (with the same parameters), make the same changes, save and then click the back button, the list on the original page refreshes automatically to show my changes.
Note that the code in the detail page where the editing/saving takes place does not change - only the way it is first displayed is changed.
My question is this: what is it about the Response.Redirect that causes the page to be refreshed when the back button is clicked, and it it possible to replicate this for the direct HyperLink approach? I would prefer to use the HyperLink method as I see no reason for the postback, but I want the GridView to refresh when the user browses back to it.
Thanks.
A LinkButton causes a postback, the response to which is a HTTP 302 redirect command triggered on the server side by your Response.Redirect. Your web browser therefore does not cache the old version of the page.
The Hyperlink control simply renders a regular <a> tag which takes you to the detail page on the client side. The browser has no reason to believe the page may have changed, so it presents the cached version when you hit the back button.
If you want to tell the browser specifically not to cache the page if the back button is used,
use the cache-control HTTP header. W3C Link,
In any case, you should provide a link on the detail page (or automatic redirect on accepting changes) which takes the user back to the GridView/summary page, so they don't have to resort to using the back button.
Edit:
Sorry, the previously provided header example was not for Asp.net, but basically you'll want to do something like this:
Response.AppendHeader("Cache-Control", "no-cache")
I have an asp.net page_load event.
When the user clicks the back button of the browser I want to set some values in the page_load event.
The problem is that when I click on the back botton the page is rendered from Cache and the page load event is not fired.
What should I do so that page_load gets fired ...other than forcing the browsers cache to clear ?
If I understand you correctly you have the following situation:
User visits page A.
User clicks a link and visits page B.
User clicks the back button and page A is displayed again. It is displayed from the browser cache, instead of being refetched from the server.
Is that right? In that case you should mark the page as no-cache. With the Response.CacheControl property you can decide what caching options are returned in the http header of the response.
I came up with a solution.
Indeed the back button has nothing to do with the server events...the page is directly renedered from the browser cache.
So what I did was that I ran a script on the page load but not ASP's page load ,rather the javascript page load.
Whenever the back button is clicked the JS page load would be raised.
The situation:
I have user controls with buttons that have hooked events. Controls with events need to be initialized in Page_Load or earlier.
I wish to spawn these user controls dynamically by clicking an Add button.
It is important to remember that events, such as click events, are not fired until just before Page_LoadComplete.
Broken Solution A:
Page_Load: Dynamically create an Add button, hook click event.
User clicks on the Add button, triggers postback.
Page_Load: Creates the Add button as usual, and hooks click event.
Page_Load: Doesn't know that the Add button has been clicked yet, so it doesn't know to spawn the user control!
AddButton_Click: Page finally aware that a new user control should be added upon the next Page_Load.
User cannot see the control they added, because another Page_Load has been triggered.
User reloads the page by clicking a button, refreshing the page, etc.
Page_Load: Creates Add button, and hooks click event. Now aware of added user control, creates user control. Hooks events within the user control.
User clicks on button within user control, triggers just fine.
Result: User has clicked to Add a new user control, the server is aware that the control should exist, but the user does not see it until they trigger the page to load again (by clicking another button, or refreshing, etc).
Naturally, I took a look at the life-cycle, and see that Page_LoadComplete occurs after events, so if I place any event-dependent code in Page_LoadComplete, all should be well?
Broken Solution B:
Page_LoadComplete: Dynamically create an Add button, hook click event.
User clicks on the Add button, triggers postback.
Page_LoadComplete: Creates the Add button as usual, and hooks click event.
AddButton_Click: Page aware that a new user control should be added upon the next Page_LoadComplete.
Page_LoadComplete: Aware of the button click, dynamically adds the control, with its own internal button click event.
User clicks on button within the added user control, but it does not trigger!!
Result: Everything works great, except the button within the added user control is inert.
The conundrum is: I need controls to spawned by a button click, which means I need to put my Controls.Add(...) code in Page_LoadComplete. Inversely, I need the controls being added to have working events, which means the Controls.Add(...) code need to be in Page_Load. I have a perfect dichotomy.
The only janky solution I can think of is taking solution A and forcing the page to reload manually after clicking the Add button, which is a waste of bandwidth and processing.
This might not be the best practice, but you can check Request.Form for the evidence of add button click during the Page_Init event and add the controls there. It should solve your problem.
I have a simple page that, on the initial load, databinds to a GridView. This gridview has sorting and paging enabled, and is also surrounded by an UpdatePanel.
When the user does the following, I receive this error:
Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Clicks the pager to change to a
specific page (lets say 5)
Clicks on a link to navigate to another page
Presses the back button in their browser to return to the page with the GridView
Grid is now reverted back to it's
original state (on page 1) since the
browser didn't track that, and so the
user clicks to go to page 5 again,
resulting in the error
Anyone know what would cause this? It only seems to be a problem when clicking on the same page. If a different page is clicked on the return visit, it's fine. If a column is sorted, then sorted again on the return visit, that is also fine. I'm not sure what specifically about clicking the page twice is causing the problem.
Here's the code for the pager:
protected void gvResults_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvResults.DataSource = SearchResults;
gvResults.PageIndex = e.NewPageIndex;
gvResults.DataBind();
}
where gvResults is the GridView, and 'SearchResults' is a List stored in the viewstate.
edit
It appears that although the gridview isn't displaying page 5 when the user returns to the page (reverts back to page 1), for some reason the browser did save the viewstate, and has the gridview at page 5. So if I click on page 4 and go through the code for the paging event, I can see that it thinks the page it was on was 5... even though the displayed content was for page 1.
Moral of the story is apparently the viewstate is getting saved when the user clicks the back button to return to the page, but the displayed table is not.
This error is related with the cached content in browser. So the solution is to disallow caching this page in browser:
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.Cache.SetExpires(DateTime.Now)
What happenes is exactly what the error says - the control the user tries to use after clicking the Back button is not the original one, since it's loaded from cache. This could be identified by volatile data you have there or by a timestamp - that I don't know.
What you could do is to put
<%# Page EnableEventValidation="false" %>
on that page, and let us know if that worked and wether it broke anything else on your page...
After searching I couldn't really find a reasonable answer; however, I did find that you can use the 3.5 preview controls w/ asp.net 2.0, so I added the History control to the page, and let that handle the back button issues.
Looks like it resolved the issue
Thanks!
When loading a page for the first time (!IsPostback), I am creating a button in code and adding it to my page, then adding an event handler to the click event.
However, when clicking the button, after the page reloads, my event handler does not fire.
Can anyone explain why?
#Brad: Your answer isn't complete; he's most likely doing it too late in the page lifecycle, during the Page_Load event.
Okay, here's what you're missing.
ASP.NET is stateless. That means, after your page is rendered and sent to the browser, the page object and everything on it is destroyed. There is no link that remains on the server between that page and what is on the user's browser.
When the user clicks a button, that event is sent back to the server, along with other information, like the hidden viewstate field.
On the server side, ASP.NET determines what page handles the request, and rebuilds the page from scratch. New instances of server controls are created and linked together according to the .aspx page. Once it is reassembled, the postback data is evaluated. The viewstate is used to populate controls, and events are fired.
This all happens in a specific order, called the Page Lifecycle. In order to do more complex things in ASP.NET, such as creating dynamic controls and adding them to the web page at runtime, you MUST understand the page lifecycle.
With your issue, you must create that button every single time that page loads. In addition, you must create that button BEFORE events are fired on the page. Control events fire between Page_Load and Page_LoadComplete.
You want your controls loaded before ViewState information is parsed and added to controls, and before control events fire, so you need to handle the PreInit event and add your button at that point. Again, you must do this EVERY TIME the page is loaded.
One last note; page event handling is a bit odd in ASP.NET because the events are autowired up. Note the Load event handler is called Page_Load...
You need to add the button always not just for non-postbacks.
If you are not reattaching the event handler on every postback, then the event will not exist for the button. You need top make sure the event handler is attached every time the page is refreshed. So, here is the order of events for your page:
Page is created with button and event handler is attached
Button is clicked, causing a postback
On postback, the page_load event skips the attaching of the event handler becaue of your !IsPostback statement
At this point, there is no event handler for the button, so clicking it will not fire your event
That is because the event binding that happens needs to be translated in to HTML. This postback that happens if bound to the page between OnInit and OnLoad. So if you want the button to bind events correclty make sure you do the work in OnInit.
See the Page Life Cycle explaination.
http://msdn.microsoft.com/en-us/library/ms178472.aspx