How to implement PRG pattern properly in asp.net webforms - c#

I have a simple three page asp.net webforms site and having an issue with the back browser button that throws the popup "...Firefox must send any information that will repeat any action.." when hitting back on the step3.aspx.
The flow is: user lands on step1.aspx, session starts, and a user quotes on a product and gets redirected to step2.aspx. On step2.aspx, you confirm the purchase by clicking an asp:Button. The OnClick event handler, btnPurchase_Click, handles the logic for purchase and redirects, Response.Redirect("step3.aspx"), to step3.aspx. Step3.aspx simply displays the confirmation page (receipt details). The session is destroyed on step3 and when the user hits the back browser button, they are prompted with the resubmit post popup. Ideally, I want the user to hit step1 on hitting back without the resubmit prompt. Each page is set to no-cache and redirects to step1 if session is invalid.
Does anyone have a suggestion for a better flow?
This site will eventually be migrated to asp.net mvc/ajax which will most likely make the PRG workflow easier to implement but for now, looking for a relatively simple way.

A simple solution is to never allow a page to render on postback, but instead accept/store whatever information it was posted, and then redirect to the next page (or itself).
That way if a user hits the back button, it is going back to a GET, not a POST, and avoids the popup.

I give this question a try. The flow you mention will obstruct the pages normal function, which you of course already have in mind. Though, i would say it can be dangerous (against the function you expect) and contraproductive. Based on what I can see from your question, I would definitively remove Page2 and Page3 and keep all logic in same and single page.
I would also be happy to hear what you are trying to avoid, with this? Is it double posts? Like a double-post of a content in a shopping cart? Partial / uncomplete inserts of data input? With the described way to affect back-buttons, you may come around one problem but rise another. A big range of browsers that can act completely different on such work-arounds.
I see two good options,
UserControl,
Create three UserControls which every each of them have each page specific logic. You can programmatically load them into the page. I.e. on bnButton_Click Event. Usercontrols are loaded with LoadControl("PathToAscxFileOnDisk.ascx").
Panels,
I would also think about three <asp:PlaceHolder></asp:PlaceHolder> or perhaps better <asp:Panel></asp:Panel> to put all logic into.
In this case you are completely free from the postback issues and can focus on moving your functions into business logic and have use the Code-File to control the flow on show/hide and populate the controls in/out from the panels/usercontrols. You can probably also control the postback / click-URL & push-enter-key.
And you mentioned Ajax,
Ajax is absolutely there to make your page stateless (which means you can work without cache, sessions, viewstate and so on. Though, the problem lies in the users possibility to navigate between pages. I would think even Ajax is of less help, while you keep the three-pages-solution.
I would personally say it is a simple task to move the aspx files into each ascx and create a aspx as a master-container. With that option you even avoid duplicate namings (like if you copy / paste the code into panels) and trouble with Page_Load flow/logic.

If I understand correctly you're not yet using the PRG.
On step 2, temporarily store the information and redirect to show it. How you do so depends a lot on your application: session, database, cookies, etc are all options with different caracteristics.
Then redirect to show that information.
Same goes on step 3.
If you hit back on step 3, you'll go to step 2. But given you're going back to a GET request, there won't be a warning. Like you said, your application destroys the session data on 3, so according to what you said the user would go to step3.
Maybe I'm missing something on what you said.

Related

Webforms Refresh problem

This is probably a simple question for every WebForms developer but I am knew to this scene. I have a page that has an "ADD" button on it that results in a jquery popup where the user can submit a form that will add an entry to the repeater on the page. My problem is that after the user adds an item, if they then hit the refresh button the item will get added again. I can't stop this with the page.ispostback because that would block the original add. What can I do here?
that's a common problem. Here's explanation and solution of the problem.
When a web form is submitted to a server through an HTTP POST request, a web user that attempts to refresh the server response in certain user agents can cause the contents of the original HTTP POST request to be resubmitted, possibly causing undesired results, such as a duplicate web purchase.
To avoid this problem, many web developers use the PRG(Post/Redirect/Get) pattern.
copied from wiki (LINK)
simplest solution can be Response.Redirect to the same page (i.e. if you page is named default.aspx write Response.Redirect("default.aspx")). if you do this browser refresh button will just load the page as if you have typed in address bar URL and navigated to it.
here's SO question How to stop unwanted postback that might be useful as well.
If there is an option to delete an item on the page (is there?), do you really have to be concerned with that happening? May want to think about that. Just a thought.

Whenever RewritePath() is called, Page.IsPostBack is false

I'm developing a custom URL Rewriter for a ASP.Net 3.5 project. This rewriter is not functionally different than most rewriters out there, the only difference being that the friendly URL collection is not loaded from a web.config file -- it's coming from a database instead. I made the naive assumption that it would be easy to develop a custom rewriter module from scratch, but now I know the mess I put myself in. I digress; let's go straight to the technical issues.
While testing the rewriter, I set up a friendly url that would take the user to a web form. Postbacks from this form should not alter the friendly address, as anyone would expect, so
http://my.web.site/app_root/FriendlyURL is always rewritten as http://my.web.site/app_root/not_friendly/form.aspx
Things are fine when the browser first loads the FriendlyURL. The page comes up and is completely functional. However, when the form is posted back to the server, the page simply reloads but, at server-side, IsPostBack is false. It's like F5 was hit, except that a HTTP POST had indeed occurred.
Unsurprisingly, when the interaction occurs through the "unfriendly" URL, the POST action triggers the postback as expected. This evidence suggests that HttpContext.RewritePath is somehow messing with the page lifecycle in a way that it loses sense of the postback operation. Any directions? Thanks.
Thanks to StackOverflow, another nearly-duplicate problem gave me hints about the core issue. In short,
Server-side components that set the PostBackUrl attribute mess up with path rewriting system during postbacks. Or the postback system is messed up during the path rewrite. (The causal relationship is unclear, but the effect is what I described in the question.)
Any asp:LinkButton, asp:Button or asp:ImageButton that sets PostBackUrl (either at form, master page, or user control levels) will cause web forms to include a __PREVIOUSPAGE hidden element whose contents are opaque, but it has some role during postbacks. This was my problem: there were several asp:LinkButtons that set the PostBackUrl attribute.
When the page (form + master page + user controls) is free of PostBackUrl'd elements, __PREVIOUSPAGE disappears and the postback mess up is gone. So after I reviewed each asp:LinkButton in the entire site, and transformed them into ordinary <a> elements, the problem was solved.

How to alter browser's back button functionality similar to eCommerce sites in asp.net

I have a web application, in which browser's back button functionality should be customized. It's like, whenever we click on browser's back button, it should take us to landing page(Login page), It should display error message saying that 'session expired. Please login again'.
I have gone through so many posts and even in stack overflow also, i saw few posts. But nothing worked for me. The java script approach i am using as a temporary workaround.Basically this JavaScript never allow us to go back. instead it will keep us in same page.
JavaScript i have used <script>history.go(1)</script>
Please help me to customize the functionality of Browser's back button.
Any suggestions will be really helpful to me.
Short answer: You cannot
A little longer: You shouldn't even try.
But if you insist: A Thorough Examination of "Disabling the Back Button." (from 2000, but since it is ASP I guess still valid for you :)
Newer dot net: Restrict user go back to previous page after signout
Ignore the older browsers do not support location.replace - IE3.2 is not considered older any more but ancient.
For this - you would need a custom solution and disabling back button will not help...
Usually you should not try to change the behavior of back button. But since this is the requirement, I would suggest the following:
Approach 1:
This calls for creating a navigation framework where you know which is the current page in the flow... This is only possible if you a sequence in which the pages will be called (like a wizard)
Approach 2:
Specific to your case : You can use jquery/javascript to identify if the back button is clicked.. If it is then you can do an ajax call to server to kill the session and then redirect the user to login page.
You can programmatically manipulate browser history using something like this:
window.history.back();
window.history.forward();
window.history.go(2); etc.
In HTML5 ready modern browsers like Chrome you can also do more advanced things including completely overwriting back button functionality using history.pushState() and history.replaceState() methods.
(https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history)
You can also go dirty and use javascript + ajax calls to react specifically to back button events, but this will also not work on some browsers. What you ask is not a native part of a web, so no matter what you will decide to use in the end, it wont be very easy or widely supported.

Chrome back button skips page

I've run into a very annoying problem that I'm having an impossible time solving. The problem is that for an unknown reason, Chrome is not registering a page in it's history and so when the user clicks the back button, it goes back 2 pages instead of 1.
The page progression is as follows:
Search-form.aspx -> searching.aspx -> search-results.aspx -> result.aspx
More specifically, when I get to the result.aspx page in chrome and hit back, it skips search-results.aspx and jumps all the way back to searching.aspx.
Thoughts?
Your page_load on searching.aspx is sending the browser immediately to another page. The only thing it ever presents the user with is a loading graphic. No links are clicked to get to the next page and Chrome is considering searching.aspx to be the last most relevant step.
Consider using javascript (I prefer jQuery) to present the loading info and cut out searching.aspx entirely. On search-results.aspx use javascript to do an asynchronous (AJAX) call back to the server for the results. While the results are being returned, you can display a nice little graphic telling them to be patient while their results load.
If javascript is not an option, then consider letting the browser's loading functions be enough. I have tried to use an intermediate page in the past for similar things and it's just a mess. Don't get tangled in that web. Either do some asynchronous loading or let the browser handle telling them their page is loading. Most people will be used to, after clicking a search button, waiting for the page to load slightly longer.
EDIT If you want a quick and simple solution, put a button on searching.aspx. Make the button do the page redirect. This way an actual form submission occurs and chrome should register the next page in its history. You could just make searching.aspx be a quick message with an OK button. They click OK and off you go.

How to maintain the controls state when navigating through asp.net page

When we use asp.net pages we can navigate from one page to another via more than one method.
This issue becomes more comlicated when you want to keep the history of current user navigation.
Lets say we have a form. The user will start to fill it, by adding values to one or more fields, but on my case he can create a navigation to another page before we posting-back the current page and thats ofcourse couses the controls to loose its values.
How can i keep the controls states through postbacks between asp.net pages.
Should i use the SessionState or maybe cache it for each user?
thanx
You pretty much have the choice of session state, cookies, or home grown state maintenance using a database. I typically get around this by combining all my pages into separate panels within a single .aspx. That way I can use object persistence and viewstate. Rather than navigating from page to page, I merely have to toggle the .visible property of different panels depending on my users' navigation choices.
RO
The answer mostly different in different application types. For example if you plan that your application will have a lot of people storing in session become an expensive operation, but for small applications it work good.
In all cases you can create some mechanism that will store temporary entered data into database, this approach will work everywhere, but it's slowly than in memory cache.
To give correct advice please explain a bit more about your application.
You could use Session variables or the ASP.NET Cache object to store state so that the user can resume filling in the form after navigating away from the page. However, if the issue is that the data entry is a lengthy process that the user may wish to pause and resume at a later time, give them the option to save their current progress to a database. If the user attempts to navigate away from the page, remind them that they may lose their current work and give them the option to save it.

Categories

Resources