Consider the scenario:
I visited a page of a website built using ASP.NET. The page is a simple aspx page containing ASP.NET server controls.
I clicked on a link which takes me to some other page on the same website.
I clicked the BACK button of the browser.
QUESTION: What happens in terms of page life cycle? Does all the events occur or the browser just displays the cached version of the page without making any requests?
I think the best answer is: It depends on the browser, especially after a post/postback.
Older browsers used to pop up a confirmation dialog to the effect of "the page contains POST data which will be resubmitted", and you could either proceed (resubmit) or cancel out. Since everything that happens in ASP.NET WebForms is part of the FORM element (ViewState, events, etc.), this would cause the entire lifecycle to be repeated.
Of course, this caused no end of trouble with duplicate submissions, so many sites had to come up with workarounds for the dupe problem, and today most browsers just fetch the page from cache instead.
...That is unless you override the cache-control headers and force the browser not to store the page in cache. Obviously, in that case, it can't be retrieved from cache, so it will usually end up being resubmitted. But, again, it depends on the browser - for example, some browsers won't allow the resubmission over SSL, so if that's the protocol in use then the user will just see a message saying that the page has expired / can't be shown.
Come to think of it, probably an even better answer is: As a site designer, you really can't depend on any specific behaviour from the user's browser when the Back button is clicked. If a duplicate submission could have negative side-effects (such as charging a credit card twice), then you need to take adequate measures to prevent that from happening. It's good practice anyway as it's entirely possible for a user to simply double-click the "submit" button by accident.
we have even tried
Response.ExpiresAbsolute = DateTime.Parse("1/1/1980");
Response.AddHeader("cache-control", "no-store, must-revalidate, private");
Response.AddHeader("Pragma", "no-cache");
to resolve this kind of problem
The page would be displayed from Cache.
usually all the events should occur, but if you have an uber browser than it could happen to display a cached page
you can just put a breakpoint in your Page Load and see if it's going to occur
Related
I have a page in asp.net by clicking on the grid in the page it takes me to the detail page,on this page i have a back button (not browser back) by clicking on the button it takes me again to the search page.
i want to see the page with changes which i have made before coming to the detail page,also i want to disable back button of browser.
i dont want to use session variable or viewstate variable.
is there any property for this scenario.
yours sincerely
Talha khan
You can't disable the browser back button. End of story. Sorry.
What changes are you making to the grid, where is it getting it's data from? You could use a cookie to store the previous pages' state if you don't want to use session or viewstate.
If the the amount of data you need to track is relatively small (in your case this would probably be a search query) you can use query string to pass the state to the detail page (which can be later passed back to the search page).
You can also use browser cookies to persist the state but I wouldn't do that (at least because they're not designed for this kind of interaction).
-- Pavel
There are several ways to solve this.
The first that comes to mind is to change the page to AJAX. AJAX would not force a page jump forward, hence there will be nowhere to go back to.
The second way is to have a check on the previouis page, for example set "Session("if_search_go_here") = Request.Url.PathAndQuery" and unset it at the right place. If this is set then the search page will just forward you to the detils page again.
probably more. :)
I'm doing some brainstorming for a portal framework, and I'm envisioning a breadcrumb navigation stack that is tracked via the ViewState (so that if the user clicks "back" in their browser and clicks some other link, the breadcrumb trail will depart from the right page). My pages are really just ascx controls that get loaded into a placeholder control on the main portal page based on the URL. When the user clicks a portal link, there is a postback that loads the original page and invokes the given link's "clicked" handler, which should then "push" the current location onto the breadcrumb stack before sending the browser a redirect instruction to change the URL to that of the page that I want to go to.
That's as far as my brainstorming goes for the moment, because once we perform a redirect, we lose the ViewState. Rather than doing the redirect, I've thought of simply telling my main portal page to replace the current page control with the target page control, thus avoiding the extra http round-trip and allowing me to keep the ViewState. But then my entire website experience occurs in the context of a single URL, so I lose URL bookmarking among other things. And if I wrap some of my controls in AJAX panels, the entire site happens in one page request as far as the browser's history is concerned.
What I would like is some way to have the browsing history and URLs behave as if each link is leading them to a new page with a descriptive URL and all that, but still have some way to know the path that the user took to get to the page that they're on (ViewState seeming to be the simplest way to track this).
Could anyone suggest some techniques I might try using?
First suggestion... You may want to look into ASP.NET MVC. However, I have to admit to some ignorance here as I'm not sure that would really solve your problem. But it sounds like the sort of thing MVC would be suited for.
Second... it's possible to override the methods responsible for saving and loading ViewState. One of the things you can do, for instance, is push the ViewState into the Session rather than sending it down to the user and back up on postback. You could easily add some custom code here.
Third... I think you may want to rethink part of your design. The ViewState really serves one purpose: It recreates the state of the page as it existed when the page was rendered for the user. If you are moving to a different page, or a new set of controls, why would you need the ViewState at all? The ViewState itself is really just a hack to begin with... ASP.NET's way of maintaining state on top of a stateless system. (but that's a whole 'nother discussion) We have other methods of maintaining state... the primary mechanism being the Session object. Why not save your breaacrumb data there instead?
I would look at using cookies. For performance reasons, you really want to avoid HTTP redirects if you can, and ViewState only works if the user submits a form, not for regular links.
You might do something like maintain several path lists in cookies that show the path that the user took to go from one page to another. Maybe you set a unique ID with each page that is applied by some JavaScript as a query string when the user clicks on a link, and the server uses that ID and the past history from the cookies to determine how to render the bread crumb on the next page?
There are a few similar questions posted here but none that really addresses my needs.
I have a list of items on one page, lets call it masterlist.aspx. If I click on one these list items another page appears, i.e. details.aspx?id=something.
The page that appears has a formview control in edit mode. If the user wants to edit the data they hit an edit linkbutton and, the form is sent into edit mode, they then edit the data and click the save button, saving the data and putting the formview back in view mode.
The issue is if the user uses the browser back button to go back to the masterlist.aspx page the page is not updated, it's pulled out of the browser cache.
I have played around with the HTTP headers cache settings but can't get anything that works on all major browsers. On some browsers I get web page expired warnings. Another option is to somehow trigger a page refresh (or partial page refresh) when the page loads using client side code, but I haven't been able to figure out how to do this.
Is there any other approach or has anyone been successful with the two approaches above, or is there some way of avoiding the issue completely.
I have to do something like this in a catalog where the browse page needs to be loaded from the DB on every load because when you hit a product page it calls out to a 3rd party to get updated info, and then save it if it should be updated. This is so when you hit the back button like you're saying the data is reloaded. What I've done is added this into the page and it seems to work fine in all browsers.
public class ProductBrowser : Page
{
protected override void OnInit(EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.MinValue);
base.OnInit(e);
}
}
What about capturing the Back button keypress event, then instead of allowing it do a browser.history.back(), you can do a document.location(...) call.
Alternatively, you could capture the back event and trigger a post-back, which could do a Response.Redirect("yourpage"). This would force the browser to issue a GET statement for the designated page, and make it refresh
With Javascript a complete solution may not be possible, but there is a workaround.
http://www.boutell.com/newfaq/creating/backbutton.html
It uses a timeout function that repeatedly forces the browser to perform a 'Forward' action. Even if someone clicks the Back button, it'll bring back to the actual page, thereby nullifying the Back operation. It may cause a flicker though.
I have played around with the HTTP headers cache settings but can't get anything that works on all major browsers. On some browsers I get web page expired warnings.
How do you get to that masterlist page? If you issue an HTTP GET and prevent clients and proxies to cache it you'd have no issues navigating back to it (and still getting an updated version).
That leaves you with server side caching (with proper invalidation when any of those items change) or no caching at all.
I'm hoping someone has seen this before because I can't for the life of me find the problem.
I'm trying to do the old "fix the back button" thing in an application and I think i have a pretty decent approach, the problem is that it relies on the application not calling page_load when you hit back and instead loading the cached version of the page.
On about 60% of my pages that's exactly what happens. It loads the cached version and all is well. On the other 40% when i hit the back button page_load calls, forcing a refresh. For reference the call to page_load is NOT in a postback.
Even stranger is that this only occurs in IE (6 & 7). In firefox page_load never gets called.
I am using ASP.NET Ajax framework on both types of pages. Anyone seen anything like this before?
--Update--
After investigating a bit more I'm finding out that when i use the search to navigate from one page to another the application behaves differently for different pages. On the broken pages the page_load gets called twice, the search gets called twice and in fiddler that turns into 2 different redirect postbacks the second of which has no-cache set.
On the working page page_load and search only happen once and it immediately redirects.
That second Response.Redirect is causing the issue. Still not sure why that's happening though.
Check what the server is returning for the cache-control http header, then try setting Response.Cache.SetCacheability()/ use the output cache page directive on the pages and see if the server is saying that the pages should be cached.
if you are using ASP.NET AJAX why not using the History server control object?
replacing History, the back button will go to the link you want.
try this
I have an asp.net application that runs exclusively on IE7 (internal web site).
When a user needs to enter data, I pop up a child window with a form. When the form closes, it calls javascript:window.opener.location.reload(true) so that the new data will display on the main page.
The problem is that the browser complains that it must repost the page. Is there any way to turn this feature off?
No, but there is a solution. Its generally considered good design to use a 302 redirect immediately after someone posts data to a page. This prevents that popup from ever occuring. Allow me to elaborate.
1) The user fills in a form and submits data via POST.
2) The backend receives the data and acts upon it.
3) Instead of returning the content to the user, the backend issues a 302 redirect as soon as its done processing the page (possibly redirecting the user back to the exact same url, if need be)
4) The page that the user will see is the page you told their browser to redirect to. They will load up the redirected page with a standard GET request. If they try to refresh the page, it will not repost the data. Problem solved.
This is a problem with the usual "postback" way of ASP.NET. If you need to reload a page without this warning, this page must come from a GET, not a POST. You could do a Response.Redirect("...") yourself. But this will destroy the use of viewstate.
asp.net mvc fixes this issue, not an ie7 only problem but a security feature of most browsers. No fix that I know of except you could just update the content in the main form with js rather than reloading the whole page
It's because the page in window.opener comes from a POST Request
Maybe you can use
javascript:window.opener.location = window.opener.location; to do just a GET request if the data can be fetched without a POST.
I do not believe that there is a way to do that. Instead, why not direct the parent window to a page without a reload.
javascript:window.opener.location='your url'
AFAIK, not via your scripts.
You might try:
window.opener.location = '#';
It should circumvent the browser reposting. And, you can adjust the hash name as needed.
If you move from page1 to page2, and want to disable the browser from going back to page 1,then add the following at the top of page1.
<script>
if(window.history.forward(1) != null)
window.history.forward(1);
</script>