I am using a ScriptManager control to load search results from server web services. There is a text box and button on the page where the user enters their search terms. When they submit their search there is a Response.Redirect that is called to the search page. I use the ScriptManager's history function to track filtering that the users can do. If you are familiar with this function the URL ends up looking something like this:
http://somesite/search.aspx?q=giant+dog#color=red&hair=long
My problem is that if the users deices to do another search with the text box and button on the search.aspx page, which causes a response.redirect, the query string changes but the hash history stay a part of the URL. This does not make sense to me because from what I understand of the Response.Redirect("someURL") it should act like it is sending you to a new page regardless if it is going to the same page it left.
I know I can set window.location.hash = "#" but I was hoping there was a cleaner way than that on the server side.
Please help! :-)
This is an old post, but I thought that I would add the solution in case anybody else was looking for this. I ran into the same problem, where the history point was being maintained across post backs to the server when a Response.Redirect() call was made. I'm not sure why this is happening and it seems counter-intuitive to me. But I believe the ScriptManager is doing something to carry the history point over.
The answer is to put your control that's issuing the Response.Redirect() call in an UpdatePanel. So, in my case, I have a button that has an event handler where a redirect is being issued. Without the UpdatePanel, the history point is preserved. With the UpdatePanel wrapping the button, all works as expected.
You can invoke AddHistoryPoint method of the ScriptManager, before Redirect.
Related
I have a webforms site that has 2 menus.
On a page you click a button, has some c# events fired by a webservice (ajax) then redirects you to another page with history.go(-1). The only problem is that in the webservice I create a sesion that makes the menus switch, the default one hides and the other one shows. The menu switch in done in the Page_Load of the Master page.
My problem is that with history.go(-1) you get to the previous page, but the old menu is present instead of the new one. How can I fix it?
the problem is that the browser is not actually loading the previous page it is using the cached page. is there a reason you can not have both menus hidden and then decide what one to show client side? this way you can let the JS .ready take care of what menu to show and then you should get the desired results when using the history.go(-1).
This artical speakes to setting cookie from the server then checking in on the client.
you could use something like this and then check the cookie to determine if the page was loaded from cache and then force a postback.
location.reload()
My fix was to add in a session the previos link, and when I need a redirect w/ cache I redirect to another aspx page, that redirects depengind on the url params where I need it to go... it was the simpler method I could thing of...
basically what I am trying to achieve is this (asp.net 4) :
If a user does a postback on an ImageButton or similar control it should cause a page Post, and go through the entire asp life cycle.
If this has just happened, and the user presses F5 or similar to refresh, it should ignore all events from the previous post and just do a regular Get.
If the user clicks Save multiple times it should register only 1 Post and not cause duplicates being created etc.
If there are update panels on the page, a Post should only update the panels data, whereas a Get(refresh) should reload the entire page.
I have had a look around and am currently using the Response.Redirect method (once processing is completed in a post it does a response redirect to the same page to replace the Post with a Get). This is unsatisfactory for a number of reasons
It causes unnecessary overhead doing two page Posts every save
I would like to have regions of the page in Update Panels, and at the moment if you change something and save it in one region, it reloads the entire page.
I found this similar SO question here which highlights a few methods, none of which looks like they will solve my needs. I also found this which is an interesting method, but I was wondering if anyone could tell me if it will solve all my above needs before I try implement it? Also, is the onsubmit event firing the only difference between a Post or a refresh mimicking a Post?
Regarding the 3rd bullet above, I have read about the jQuery .one() function, but I am looking for an application wide solution, as most of the app has been developed without this in mind.
Thanks in advance!
I have an ASP.NET form that the user can make lots of changes to, each time they make a change the page PostsBack and the details are updated.
If the user hits the browser back button they go back through all the previous versions of the page.
Is it possible to stop each PostBack being treated by the browser as a new page?
So the would make any changes they like and if they hit the back button it brings them to the previous form and not the same form but a different version?
I know I could use AJAX to update values but I'm not an advanced coder so trying to keep things simple as I haven't used AJAX before.
Ajax is your only solution.
There is no way to remove a page from the browser history. Javascript is explicitly denied the capability.
Now, you could, potentially, stop them from using the back button at all. Although this might result in unhappy users and I'm not 100% certain it works in all browsers.
function body_onload(){
window.history.forward(1);
}
You could use a trick to do it.
On postback you can set a session bit to true saying they submitted that form. On your postback check to see if that value is set. If it is they are trying to do it again and you can just abort it. It wouldn't prevent the postback per se but you could control the logic and prevent it from DOING anything.
I personally would explore ajax as Jquery provides some nice ways to do it and it'd be a learning experience but I suppose this would work as you are asking. On a per session basis. If you only want 1 submission ever use a database to store the activity.
You could use UpdatePanel: http://msdn.microsoft.com/en-us/library/bb386454.aspx
I have a master page with a logout link on it. When the user clicks the link I call the following method:
private void Logout()
{
SessionBll.DeleteSessionEntry(this.sessionId);
FormsAuthentication.SignOut();
Roles.DeleteCookie();
LogHelper.Location = string.Empty;
LogHelper.Info(logger, HttpContext.Current.User.Identity.Name,
MethodBase.GetCurrentMethod().Name, "User has been logged out from
Administrator.Master", LogMessage.LoggedOut);
FormsAuthentication.RedirectToLoginPage();
}
Now, when a user is on a page and they click the link, the normal page cycle happens and this method is called.
The problem with this is that the user shouldn't have to wait for the page cycle, they should be taken to the logout page as fast as possible (as long as it takes to run the logout method on the server).
How do I skip the page life cycle, yet still call this method?
Thanks.
The problem with this is that the user shouldn't have to wait for the page cycle
I would argue that the problem is that the page is apparently doing too much in the page cycle. In WebForms, the page cycle happens. It's just how it works. Consider this...
In order to interact with the code-behind, the client-side form needs to POST to the page.
In order to handle the POST, the page needs to exist in memory.
In order to exist, the page needs to go through its standard creation steps in its life cycle.
Without seeing any actual code, my gut reaction is that you're doing too much on Page_Load. Refactor it out. Only do what you need to do to load the page. Not to process data, not to do all kinds of back-end work, just load the page. This should be a fairly light process. Then logically plug in your necessary background work where appropriate. (In WebForms, and this is a major pet peeve of mine, this often ends up as wrapping a lot of stuff in a conditional to check IsPostBack.)
Now, there is something you can do. Based on your question, it sounds like what you want to skip is the loading of the current page, and instead go straight to the logout page. Depending on your setup, you have a couple of approaches:
Make the logout link nothing more than a simple link. That way the browser will only request the logout page, as opposed to making a form POST to the current page (as it does with, say, a button or a LinkButton).
If the logout page actually needs some kind of value POSTed to it, make it its own HTML form with the action set to the logout page. This involves relying less on the server-side drag-and-drop controls and more on just crafting some simple HTML (which is always a good thing to be able to do in web development).
Or, thinking about your question a bit more, are you asking how to make the logout page skip the Master Page's cycle? If the logout page uses the Master Page, then it can't skip it. The page has to exist before it can be used. But you can create a standalone logout page without a Master Page which does nothing more than process the logout (and then redirect, I suppose, to another page). This would process the logout quickly, but overall still require that a page be loaded somewhere. Which brings us back to the point that the problem is that the page takes too long to load, not that you're loading a page.
You can't skip the page life cycle; what you can do instead is this:
Change that logout link to a normal link (<a href="...">) and on Page_Load of the Login page, execute that code you posted but only if(!IsPostBack)
Edit
If your Login page needs to know (as you put it) when to execute your cleanup code; you can pass a parameter on the logout link as so:
<a href="Login.aspx?Logout=y" > Logout </a>
And then check on Page_Load:
if (!IsPostBack && Request.QueryString["Logout"]=="Y" )
{
//Your code here
}
This is super fast.
Use something that doesn't have the lifecycle - ASP.NET MVC as someone suggested or create an .ashx (handler): logout.ashx would simply log out the logged-in user. That would work without having to change frameworks.
This is not often done, though, usually you'd use a different page, which would still have a full lifecycle (as per Icarus' answer).
Call entirely different page that would only perform Logout task an no other relevant code. That way, you don't have to worry about page life cycle.
Is there any pattern or kind of "least requirements list" to follow for ensuring an asp.NET application to support BACK button of the browser for each aspx page?
thanks
In general, the back button on the browser will take you to the previous HTML GET or POST that occurred. It navigates by page-wide transactions, so anything done dynamically cannot be navigated that way. Also, the back button doesn't rewind code execution, so if you are determining something based off of a Session variable or something similar, that won't be rewound either. Obviously, it won't rewind database transactions either.
In general, if you want to support the back button, you'll need to make sure to divide everything you need to navigate between with said button is divided by an HTML transaction of some sort.
Again, you're going to run into issues if your page display is dependent on server-side control that changes from one post to the next. This is one reason you see some forms feed a 'Page has expired' error when you try to navigate back to them.
Not really... It depends on your application flow.
There are things that make supporting the back button more awkward.
for example using pure ajax to change the majority of the content on the page,
will look like a 'new' page but wont be compatible with the back button (though you can fudge it)
another example is posting back to the same page more than once, as this can make it appear like the back button is not working, and at the same time re-doing your request (and therefore database transactions)
Fundamentally it depends on your application requirements.