Can I change the browser URL while maintaining ViewState in ASP.NET? - asp.net

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?

Related

Possible to only update part of page and change query string parameters at same time in asp.net?

Is there a way to only update part of the page and update the query string parameters at the same time without completely refreshing the whole page in ASP.NET?
I only need to update the "main" section of my page and not the whole page. I understand I can do a partial page postback (or use asp ajax) to do the partial page update, but then how do I update the query string parameters in the URL at the same time? Is that even possible?
Or is it not possible and I'll have to just do a Response.Redirect in the code behind of the partial page postback redirecting to the same page with new query params and just let the whole page refresh?
Use pushState.
This new feature offers you a way to change the URL displayed in the browser* through javascript without reloading the page. It will also create a back-button event and you even have a state object you can interact with.
window.history.pushState(“object or string”, “Title”, “/new-url”);
Described here
You have absolutely zero programmatic access to the address bar. The only way to change it is to redirect.
You could, however, do it like some sites do and provide a "send a link to this page to your friends" area. Youtube comes to mind - see how it provides a URL, querystring parameters included, for you to copy, should you wish to send someone a link to a video starting from some specific point.
Also check the handy "Share" link right under your question. You could provide a link like that, with the target URL, so for the user it's just a matter of right-clicking and copying from the context menu. A link well structured into your site is more user friendly than having the user copy directly from the bar, or from a text box. Specially for mobile browsers, where the sequence is usually press-and-hold, then copy. Copying from the address bar, on the other hand, may involve selecting the address bar text, which in some Android devices is a pain in the ass.

ASP.NET page caching and session variable

I have a asp.net webpage that displays a link Login or Logout depending on a session variable "IsLogged". I want to implement caching in that page. But after applying caching the Login/Logout becomes inconsistent with the session variable. What is the best approach to address this problem so that I can also apply caching in that page?
Thanks,
Partha
I am not sure how you are caching specifically but you could break your page up into two user controls (ascx).
Your aspx page could contain the user control to that shows the login information (make sure that when you load the user control with a dynamic url so that the caching ignores it because the address is diff everytime like:
yourSessionInfo.ascx?stopcache=32487239875 (the number could be just current time in ticks)
You just need something that changes in your url so that the page 'looks' like it is different and reloads.
Then have the rest of your page in another user control that has a static url:
yourRestOfPage.asx
Notice nothing changing in the url so page can be cached.
Not sure if this will solve your exact problem but it should at least start you down the right path.

What is the alternative to Response.Redirect() asp.net?

Hi One of the tips in "website performance tips" in various blogs says "Avoid Redirects". In my case, I am using Response.Redirect for the same page. I am passing a querystring and displaying appropriate information to the user.
Response.Redirect("FinalPage.aspx?NextID=" + ID);
So in our business logic, i am reloading the same page with different information.
So how do i avoid redirect? Is there any other alternative? BTW, my aim is to gain some performance there.
Redirect is the R in the PRG pattern which is an accepted pattern for processing posted requests. So it is definitely not evil.
However, there used to be a common interview question: "What is the difference between Server.Redirect() and Server.Transfer() and which one must be used?". People used to say Transfer because it did not involve a round-trip but web has changed so much since then. In those days you could not re-use the the common logic in the views unless you use Transfer or Redirect, but nowadays especially with ASP NET MVC there are tons of a ways to do that.
In your case, I am all for PRG and I believe redirect is semantically more correct. Also it prevents the form being re-submited if user clicks F5 or refresh.
The recommendation is for unnecessary redirects.
Your case is different - you are passing in information to the page, this is not strictly the same thing as a regular redirect (i.e. a page that moved).
You can also do a Server.Transfer, which does not require a new request to come in, thus lessening the load on the server. More information comparing the two is here.
In your case, you do want to do a Redirect because you are modifying the query string and changing something on the page, as opposed to shifting processing of the initial request to another page.
The main "evil" if it could be called such is that redirects require an extra round trip; the client requests one page (usually the same page, specifying that a particular button was clicked), and the server responds saying "request this page instead", and the browser then complies, resulting in the server actually serving up the next page.
It's sometimes necessary to do this, however there are now much better ways to control navigation in a website. For instance, instead of a "form" button that causes a postback and redirect, you could use a LinkButton that will behave like a hyperlink, allowing the browser to request the new page directly. You could also use a MultiView that shows different ASCXs, and control navigation by view-flipping (however, understand that this can have its own performance implications, especially when using them in a nested fashion).
I think if you want to redirect to same page then instead of doing Response.Redirect("FinalPage.aspx?NextID=" + ID); you could use NextID in ViewState also or Hidden Field so that you would not required to redirect SAME page and then check that hidden field or viewstate instead of checking QueryString
:D

can i repost or carry POST data (if so, can i do it with redirects?)

I want to redirect the user to another page to fill out a captcha but i would like to keep the post data, and if the captcha pass to send it 'back' and complete the previous page action.
When/if the user succeeds i like to add an captchaPass=true and would like access the post data and continue processing. Right now i am using redirects but ATM i am not required to use it.
Is it possible to carry the post data? keep in mind i may the user access multiple pages so separating data and not having a mixup is necessary.
One idea is to get and save all posted data [1] on the captcha page, and then recreate a middle white page with this form data and automatically make a new post to the previous page.
Can this work with out any issues with hash checks and security ?
Is there a better idea with out this white redirect page ?
[1] One other issue here, how to send this posted data with the redirect ? and not change the url - or make it too big to accept it. Keep in mine that a server transfer may not good idea because is complicate the thinks on captach post back.
Update 1
The basic idea here is how some one capture the full post back of a page, show a different one page and then send the post back data to the original first one.
The reason is to stop a bad user, or an attacker bot program that try to bring down the pages/server by making many post back from different pages in short time. All that happens with out javascript, and most attackers use custom made programs that just make post of data to all page together try to bring down the system.
For example, if a page have a search box, is very easy for most of the the site to bring them down by start making hundred of random search with wildcard (called and Dos Attacks using SQL wildcards) and make the sql server and the computer spend his time and cpu to search and search thinks. So to prevent an attack like this you need to recognize multiple post backs from the same computer, and then the next step is to redirect him to a captcha page to block him out in case that is a computer program.
Other example, many page have email submit, very easy you can submit hundred times the email of his and full his mail box in no time with hundred of emails, or on a store to place all items on the cart again and again and full the database with stuff like that.
So ajax and javascript is not working in this case, and we need a way to redirect him after the post back to a page that can check if is a real user or an attacker and stop him - but if is a real user must return back to his normal action.
Update 2
This all must be done in a general way, eg on BasePage, or on Global.asax or somewhere that is independed from the content of any page. Because we try to prevent a DoS attack, or multiple submit anywhere on any random place of any random page.
Yes I know how you can place a captcha on the contact page, but this is not what this question was first asked for - this questions asked how can carry post data to one different page, keep them there and then resend them back to the original one.
The obvious solution is to read all post back, and save them on the form, and then read them back and make on fly a form only with that data and make the post back. Here I am asking if there are any other better than this solution.
Other Applications
There is also the case that a user is inside a page that request authentication, but the authentication ticket has expired, and the user make post back. In this case we need to keep somewhere all the posted back data, to proceed with the login page, and resend them back to the first page that request the authentication.
Sure, just write the form data out to the captcha page in hidden elements with the additional captcha fields added to the form. Have your submit action post the whole thing back to the original. Using ASP.NET it's probably easier to have the captcha written to the same page with the form fields hidden, but you can do cross-page postbacks as I've described above.
Cross Page Posting might help you.
Why not implement the CAPTCHA with AJAX? Load the captcha object and form with Javascript in a div perhaps displayed lightbox style, accept the user input and post it to your server for validation, hence continue with the users post request or keep them there until they get it right (or cancel).
A more specific situation example:
Give the form submittal button an onClientClick value of some Javascript function. This function decides if this particular form needs a CAPTCHA. If it does it loads an interface for taking the CAPTCHA (which you'd need to do with some server-side code) and inserts the CAPTCHA's input element to the form that the user clicked to submit.
Once the user has entered the CAPTCHA input and clicks some button whose click event is bound to return to your first JS function, the Javascript intercepts this action and posts the full form, all the data from the original form and the CAPTCHA for validation. Your server script can now process all this at once!
This is the best solution I can think of that works similar to how you've asked, but I can't imagine why you want to perform the CAPTCHA on a different page.
Server.Transfer with MultiViews, Panels like control is fine with you? In this way, no need to bother about the Data Maintenance and Postbacks. You can do the validations in javascript.
You can keep both functionality in the same page to avoid moving data from one page to another page/Bring the data back to original page. You can utilize Session for this intermediate operation. Set it back to associated controls across Postback. You can create a class, Instantiate it and Initialize the control values in this class object. Save class object in Session. On Postback, You can reassign the values to the associated controls. This will definitely keep the things simple and without much complexity.
Doubts ?

Options for Dynamic content in ASP.Net

What choices do I have for creating stateful dynamic content in an ASP.Net web site?
Here's my scenario. I have a site that has multiple, nested content regions. The top level are actions tied to a functional area Catalog, Subscriptions, Settings.
When you click on the functional action, I want to dynamically add content specific to that action. For example, when Catalog is clicked, I want to display a tree with the catalog folders & files, and a region to the right for details.
When a user clicks on the tree, I want a context sensitive details to load in the details region (like properties or options to manage the files).
I started with UserControls. They worked fine as long as I kept loading everything into the page, and never let one disappear. As soon as one disappeared, ViewState for the page blew up because the view state tree was invalid.
(I didn't want to keep loading stuff into my page because I don't want the responses to be too huge)
So, my next approach was to replace my dynamic regions with IFrames. Then instead of instantiating a UserControl, I would just change the source on my IFrame. Since the contents of the IFrames were independent pages I didn't run into any ViewState problems.
But, I'm concerned that IFrames might be a bad design choice, but don't fully understand why. The site is not public, so search engines aren't a concern.
So, finally to my question.
What are my options for this scenario? If I choose an Ajax Solution (jQuery), will I have to maintain my own ViewState? Are there any other considerations I should take into account?
Controls that are added dynamically do not persist in viewstate, and this is the reason that it doesn't matter if you use AJAX or iframes or whatever.
One possible work-around is to re-populate controls on postback. The problem with this, is the page life-cycle (simplified) is:
Initialize
LoadViewState
Load Postback Data
Call control Load events
Call Load event
Call control events
Control PreRender
PreRender
SaveViewState
Unload
What this means is the only place to re-add your dynamic controls is Initialize -- otherwise posted data (or viewstate information) is not loaded into that control. But often, because Viewstat/postback data isn't available yet in Initialize, your code doesn't have the information it needs to figure out which controls need to be added.
The only other work-around I've found in this situation is to use a 3rd party control called DynamicControlsPlaceholder. This works quite well, and persists the control information in viewstate.
In your particular case, it doesn't seem like there are that many choices/cases. Is it practical just to have all the different sets of controls in the page, and put them inside of asp:placeholder controls, and then just set one to visible, depending on what is selected?
Some other options:
Content only appears to be dynamic. You load enough controls on the page to handle anything and only actually show what you need. This saves a lot of hassle messing with view state and such, but means your page has a bigger footprint.
Add controls to the page dynamically. You've already been playing with this, so you've seen some of the issues here. Just remember that the place to create your dynamic controls for postbacks is in the Page_Init() event, and that if you want them to be stateful, you need to keep that state somewhere. I recommend a database.
you've got a number of different options, and yes, IFrames were a bad design choice.
The first option is the AJAX solution. And with that there's not really a viewstate scenario, it's just you're passing data back and forth with the webserver, building the UI on the fly as needed.
The next option is to dynamically add the controls you need for a given post, everytime. The way this would work, is that at the start of the page life cycle, you'd need to rebuild the page exactly as it was sent out the last time, and then dump out all the unneeded controls, and build just those that want.
A third option would be to use Master pages. Your top level content could be on the Master page itself, and have links to various pages within the website.
I'm sure given enough time, I could come up with more, but these 3 appeared just from reading your problem.
dynamic controls and viewstate don't mix well, as noted above - but that is a Good Thing, because even if they did the viewstate for a complex dynamic page would get so bloated that performance would diminish to nil
use Ajax [I like AJAX PRO because it is very simple to use] and manage the page state yourself [in session, database tables, or whatever works for your scenario]. This will be a bit more complicated to get going, but the results will be efficient and responsive: each page can update only what needs to change, and you won't be blowing a giant viewstate string back and forth all the time

Resources