Apparently I am not familiar with the Life Cycle of a page in ASP.NET. This became apparent when I wanted to dispose of a Session variable after I left the page. I did what made the most sense:
protected void Page_Unload(object sender, EventArgs e)
{
Session.Remove("ServiceSearch");
}
What I didn't know is that this would be called when I go from AND to the page. What I am wanting to do is dispose of that Session variable whenever the user leaves the page. How do I do this?
Page_Unload refers to unloading the Page object right before it is disposed after parsing and creating the page. It has nothing to do with leaving the page. Like #Nick says, there is really no good way to tell that, except to control every exit path. And you can't, because you can't control when the user hits back, or goes to google.com and then pastes in the url they were just at into the browser, etc.
If you want to remove the Session variable just so it doesn't get re-used unintentionally, a better solution is to overwrite the Session variable every time you enter the page, and just let it be disposed with the session on its own time when the session expires.
Session data is useful for storing data beyond the lifetime of a page. If you don't want to store it beyond the life of a page then Session data is not for you here.
If the user leaves the page via a link you could possibly create a link button that is hooked up to a method on the same page. That method would remove the session and do the redirect.
I would hope there is a better solution though. Although, from my understand, there is no page event to use in your case because the page would have to reload to execute the remove session code. When the user leaves via some link the page is not reloaded.
You may possibly be able to handle it via javascript. I've been in situations where I wanted to leave and I got a popup box about some bs. You could probably use the same technique to fire AJAX to remove the session.
I faced a similar situation on php login- a logged-in user could use the arrow back and forth to login page. So, I simply add :
session_start();
session_unset();
session_destroy();
above the html script of the login page so that if the logged-in user arrowed back, the session is both unset and destroyed. Any attempt to arrow forward will only lead to the login page-requesting user login credentials-essentially, the user is logged out any time they arrow back!
Hope this helps!
Alfred
Related
I have one button on page, page name abc.aspx . when user click on that button
it should redirect to finishwork.aspx page.
After finishwork.aspx page user must not go back to abc.aspx page. when user press back button in browser, he should be redirect to workallreadyfinish.aspx page
Disable caching on that pages and avoid caching the page.
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
location.replace() can be used to replace your page in the history.
There are many ways to accomplish this, but, as you are using ASP.NET and I'm going to assume, WebForms, why don't you make use of the <asp:Wizard> control?
You will be able to have a much detailed control over your steps and block the user to go back and all sort of nice things.
If you want to take the normal way, you can always warn the user that the page will no longer be valid using a javascript event.
You can also make use of hashing and submit the form by an ajax call instead of a normal POST
You can write a cookie once the form is submitted and the next time, show such warning, so even if the user goes back and press the Submit button again, you will not care. Remember to erase the Cookie on if (!Page.IsPostBack) { ... }
Having your user workflow around the browser back button is not such a good idea.
Browser back buttons are not entire in your control.
If you want to provide a logical back in your application, use a back button in your application.
If you only want that a user cannot go back to a page, you should tell the browser not to cache it set the page to expire.
You can use javascript function for this:-
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
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 am using VS 2005, C# 2, ASP.Net 2.0
I am unable to find out how to track that user pressed F5/Ctrl+F5/ Open a new Window(Ctrl + N) in ASP.Net.
I know that there is a Page.IsPostBack property, which tells that a page is loaded in response to an action taken by user.
I am just curious to know, that why isn't there a property as IsRefresh or Page.IsRefresh in ASP.Net, which will return true,
whenever user takes any of the above actions.
Is there a way to know this?
Actually my problem is that i have a DLL using which all of my aspx pages are inherited, I have to
insert some values in a table whenever the page is opened for the first time that's it, if user just opens the page or do not take any action,
an entry should be inserted into the database, but as far as I have tried, I controlled it anyhow using the Page.IsPostBack property, but I got stuck
in the refresh case, as it is inserting records unconditionally.
Similar to using a function in Global.asax (as others have suggested) you could use a session variable "flag". When the page first loads set a session variable and then just check against it in your page load function:
if (Session("visited") != "true"
//page has not been visited, log visit to DB
Just make sure you set the session flag sometime after the above check during the page load.
It won't be exact (sessions can timeout while a page is active, users can completely leave the site and come back in the same browser and the session stays alive, etc) but for your tracking it is much better than counting every page hit in the DB.
Perhaps you want the Session_Start method in the Global.asax file, which will be triggered once at the start of each user session?
In your Global.asax file, add or edit the method:
void Session_Start(object sender, EventArgs e)
{
}
why isn't there a property as IsRefresh or Page.IsRefresh in ASP.Net
Because ASP.NET cannot possibly know. The browser does not send any information that could allow it to determine whether the page is being requested due to a refresh or normal load. You will need to reconsider your requirements: what is the actual purpose of the database logging?
Session_Start method in Global.asax file is fired every time when a browser session is started. You can use this method to count number of unique users on your website.
Session_End method in Global.asax is fired when a session ends (explicitly or timedout). So you can decrement the count here.
Hope the above to example uses of these methods helps you understand how you can use them.
Because of the stateless nature of HTTP protocol there is no way to tell apart the initial load from the refresh
As has already been said. This isn't possible. A request issued due to a refresh is no different to a request issued the first time the page is loaded.
It sounds to me like you are trying to track page views somehow. This is certainly possible though it will require some work on your part. Your best bet is probably to log the URL of the page. You may also want to include the query string in order to differentiate between page loads for different pieces of data (if this happens in your application). You will also want to log the ID of the current user, and the ID of their session.
You can then make sure that you don't insert two page views for the same user for the same page in the same session, effectively filtering out any reloads of a page.
You do need to be aware that this isn't the same as detecting a refresh, what you are detecting is two page views in the same session, this could be a refresh, or it could be use of the back button, or just reloading from the address bar.
My suggestion would be to create a cookie on very first load, then on Page_Load check to see if the cookie exists. If it does, don't insert the record. You can use Session_End to destroy or create the cookie as someone suggested if that works with your application's architecture.
First of all, thanks for reading.
I will describe my situation as explicitly as I can.
I have a page where users can leave comments.
Here's the commenting flow
A-1. 'comment' button is clicked
A-2. a modal popup with a textbox is shown using ModalPopupExtender in ajaxtoolkit.
A-3. User types a comment in the textbox, and click "ok".
However, when user is not logged in, expected behavior changes.
B-1. 'comment' button is clicked
B-2. a Login modal-popup with id & pwd textbox is shown.
B-3. User types ID & pwd, and click ok.
B-4. Comment-modal-popup is shown
B-5. user types a comment and click ok.
I have a PROBLEM handing this case.
When B-3 occurs, page is posted back, i log the user in, update session object, and I Response.Rediect() the page to itself to display correct logged-in status (i have to..).
After redirect, in Page_Load(), I need to check some values to show Comment-Modal-Popup.
But I'm not sure how..
Here's what i considered
ViewState
i just can't use it since the page was redirected not posted back.
QueryString
I could have add "showCommentPopup=1" on URL when redirecting, but that will leave unwanted QueryString in URL. I don't want users to misuse it.
Session
I actually used Session object. Before redirection, I set Session[ "ShowCommentPopup" ] to true. In Page_Load() if it is set, i remove it and show the popup.
using Session like i did doesn't work correctly when user opens same page in multiple tabs.
user opens two tabs(in Firefox) with same URL
user follows steps from B-1 to B-3 in first tab.
before the page is redirected between B-3 and B-4, user refreshes second tab.
if the timing is right, comment-popup is shown in the second tab.
I expect to hear great insights from stackoverflow..
I haven't tried this but I think if you store your ShowCommentPopup flag in the HttpContext.Items collection instead of the session and then use Server.Transfer instead of Response.Redirect you should be able to achieve the desired results.
HttpContext.Items is a dictionary that can be used to store data whose lifetime is the lifetime of the request. This means a second request from a different tab or window will have a different HttpContext.Items dictionary.
Server.Transfer is somewhat like Response.Redirect in that it allows you to load a "different" URL instead of the original. However, while Reponse.Redirect initiates a new request, Server.Transfer transfers the existing request to the new page on the server.
A better explanation of the differences between Response.Redirect and Server.Transfer can be found here.
Example
bool showCommentPopup = false;
if (HttpContext.Current.Items["ShowCommentPopup"] != null)
{
showCommentPopup = (bool)HttpContext.Current.Items["ShowCommentPopup"];
}
//...
HttpContext.Current.Items["ShowCommentPopup"] = true;
You've clearly thought your solutions through! I'm guessing the problem with the Session was that they could comment on a different page than the one they logged into. You could get around this by storing the session var, not as a bool, but as the page to show it on:
var uniqueString = this.ToString() + uniquePageID;
if (Session["ShowCommentPage"].ToString() == uniqueString)
//show modal & remove session var
Now your program only "breaks" when the user visits the same object in two different windows, logs in on Window #1, and refreshes on Window #2. And it's not really breaking since they wind up commenting on the same object either way.
The reason I used uniquePageID, is cause I'm figuring you have a template page ("showObject.aspx") with arguments on which to show ("showObject.aspx?objectID=3"). In order to make sure the comment is left on the same ID, it needs to be present in uniqueString
I have an have an ASP.Net page which contains a button. This Page contains a ServerSide Paypal button.
When pushed my server does various clever things on the back end and then rewrites the response as a form and some javascript which posts this form to paypal..
This all works great.
However, if the user then elects to click back, they will arrive at my generated self-posting form and that will forward them again to Paypal.
I thought if I could find a way to have my generated form page not exist in the history, then this will solve my problem. but I have no idea how to correct this.
How can I remove my page from the history or just have it never appear?
Update: Thanks to all... Those are some great answers. Upvoted all good ones but went with splattne on account of clever use of hidden field rather than cookies for basis of decision.
window.location.replace(URL);
window.location:
replace(url)
Replace the current document with the
one at the provided URL. The
difference from the assign() method is
that after using replace() the current
page will not be saved in session
history, meaning the user won't be
able to use the Back button to
navigate to it.
I'm not sure if that can be done. But here is an idea how you could prevent that resubmit of the form.
You could insert a hidden input in your form which at the beginning would be empty. On submit you'll write a value in that field and make sure you check on every submit attempt if this field is empty.
If it is not empty on submit you know that the form was previously sent and you could warn the user.
As a web application, you'll never have full control of the user's browser. Even if there was a way to instruct the browser to not store the page in history, which I doubt, you can't be sure it'll work. For example, a clever user could tweak an open-source browser to store every page in history, no matter what.
I think you should try to approach the problem from another angle. You could, for example, detect that it's the same form which is being forwarded and not send it to paypal the second time. The important thing is to do it server-side.
Perhaps you could set a cookie before submitting the form.
When the page is loaded, check for the existence of that cookie (meaning the form was already submitted). If found, instead of automatically submitting the form, automatically go back (window.history.back()) again.
I'm not sure if you can do this easily with PayPal integration, but the
"Post / Redirect / Get" pattern can be used to address this problem
A useful Hint for some might be this...
window.history.go(-2);
particularly in the advent of a load failure warning popup.
You could simply programme your page not to submit, or to do something / navigate somewhere else, if window.referer is the Paypal page you are trying to avoid invoking a second time.
protected void Page_Load(object sender, EventArgs e)
{
Page.RegisterClientScriptBlock("", "<script>if(history.length>0)history.go(+1);</script>");
}