In asp.net is it a requirement to rebuild the whole page during every callback? For example my web page is split into three distinct areas and I have an update panel for each area. Lets say I want to update the third area, do I have to bother with any processing of the other two areas?
For example lets say there is a grid view in area two. The update panel in area three callbacks to update its content. Do I have to rebind the grid in area two?
Thanks,
AJ
Yes, this is how ASp.NET is done. If you use an updatePanel / AJAX partial update, you may get away building only part of the page. But then, your viewstate may be a problem.
What you see is basically one of the disadvantages of the ASP.NET model.
By default, "UpdateMode" is set to "Always" for UpdatePanels which means they update whenever anything "happens" on the page.
Try setting "UpdateMode" to "Conditional" for all your three UpdatePanels and see if that helps. (FWIW this is standard practice for me as part of writing the UpdatePanel definition. If you need to update an UpdatePanel when something happens on a different part of the page, you can use Triggers or update it with .Update() in code behind)
bgs264
Edit
I think I misunderstood your question originally; my suggestion above may improve page rendering times as partial postbacks result in less code being sent back and forth between client and server.
But yes as per other answer, all the controls have to go through their lifecycle (Init, Load, Render) on every page load / postback.
Related
We have a site where all pages are output cached, i.e. the caching is on aspx-level with VaryByParam="*". Now there is a requirement to make a gallup control, i.e. a small "How is this site working for you?" and then when the user clicks an answer the results are shown.
The gallup is implemented as a usercontrol that is added to the master page so gallups can be added to any page to which a gallup is created in the cms. The problem is that output cache naturally caches all clicks so when user no 2 votes he sees the results that where calculated after the first vote on that alternative.
Now I'm trying to use cache substition. I added an asp:Substition tag where the user control used to be, load the control dynamically and render it (using this approach http://coderwall.com/p/4ajzqq). The problem is that the postbacks that voting triggers is never fired. Apparently the method that the substition control executes is loaded outside the page life cycle or too late.
Any ideas?
Regards,
Mathias
I solved this by skipping the substitution control and just used the user control as normal, so the gallup/question view was output cached. Then in the click handler for the answer alternatives I added
Response.Cache.SetNoServerCaching();
which exempted the results view from output cache and hence it was updated as it should.
It is also possible to use Response.Cache.SetNoServerCaching() in Global.asax, using VaryByCustom. It merely requires sensing in Global.asax whether the page is a post-back or not. Here is a code example.
I'm trying to code what I think is a fairly routine AJAX pattern using TreeViews and UpdatePanels. My situation is this:
I have a TreeView within an UpdatePanel. I have a Literal within another UpdatePanel. When the user clicks on a node within the TreeView, the contents of the Literal are updated. Now, since the whole thing is asynchronous, there is of course a time lag between the click and the update of the Literal contents. During this time, I'd like to do two things:
1) Show an UpdateProgress, and
2) Clear the contents of the Literal
This is so that the user doesn't have to stare at the old contents while the new text is getting loaded asynchronously.
I can't seem to figure out an easy way to accomplish (2). I've been reading up on client side callbacks and using GetCallbackEventReference, but it seems like a very complicated approach to what is seemingly a simple problem.
Ideally, I would like to leave TreeView alone to do it's work. I don't want to get the contents myself and add them to the TreeView using JS. I'd just like to detect the node change event at the client side, clear up the Literal, and let TreeView go about with its normal operation.
Is this possible? Or are client call backs my only option?
You'll be wanting to play with the PageRequestManager from the ASP.NET AJAX library. Here's the MSDN reference for the PRM - http://msdn.microsoft.com/en-us/library/bb311028.aspx.
Just be for warned Microsoft have stated that the TreeView can be problematic within the UpdatePanel and you'll also want to be very careful of the performance, particularly if you have a large TreeView (see my article on optimising the UpdatePanel performance - http://www.aaron-powell.com/blog.aspx?id=1195). You should really look at something like a jQuery plugin (eg: http://bassistance.de/jquery-plugins/jquery-plugin-treeview/).
But to actually answer you're question you need to:
Have a BeginRequest event handler which will then clear your literal and can even show a Loading (I'm not a fan of the UpdateProgress, I prefer much more granular control I get from doing it myself)
Use the EndRequest event to ensure that the Loading component vanises
You could also make the TreeView a AsyncPostbackTrigger of the 2nd UpdatePanel on the page, or just call the Update method on it during the async postback of the TreeView
i had the same problem and fixed it by creating a hidden html element that overlaps the area i want to hide. I show it onSubmit and hide it in the window.onload during a postback. It's not pretty, but it works and should be fast.
I have a web form that has multiple ListBoxes, TextBoxes, DropDowns. If I put one UpdatePanel around the whole page, I noticed the page is slower. Is this because, every control is being updated? If I put different UpdatePanels around each control, I noticed the page has a better response. Is it right to assume that this is because I have more control of which parts of the page are updated based on selections from ListBoxes and DropDowns for example?
Thanks,
X
each update panel generates a round-trip to the server (i assume you're using a timer or something to cause this)
the general rule would be to group controls in an update panel that must change together, otherwise separate update panels makes more sense
I use update panels with a set of related functions in mind. I find that for my apps when there are related pieces of content on a page, such as a search tool, it is best to be placed in its own update panel. Be careful putting too many update panels however on your page as the client will have to download more code to make it run.
A rule that I use is to set the update mode of all panels to only fire when children are changed, and in some cases it's best to do it programmatically in your code behind. This is best in cases where you have a section of items in another update panel but both don't need to be updated or the parent one only needs to be updated on occasion.
By triggering the panels in your code you will create a little more work for yourself but in the end you will also have a lot more control over the user experience and this may help you also send fewer bits down the pipe.
Andrew
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
I have a problem with maintaining state in an ASP.NET AJAX page. Short version: I need some way to update the page ViewState after an async callback has been made, to reflect any state changes the server made during the async call.
This seems to be a common problem, but I will describe my scenario to help explain:
I have a grid-like control which has some JavaScript enhancements - namely, the ability to drag and drop columns and rows. When a column or row is dropped into a new position, an AJAX method is invoked to notify the control server-side and fire a corresponding server-side event ("OnColumnMoved" or "OnRowMoved").
ASP.NET AJAX calls, by default, send the entire page as the request. That way the page goes through a complete lifecycle, viewstate is persisted and the state of the control is restored before the RaiseCallbackEvent method is invoked.
However, since the AJAX call does not update the page, the ViewState reflects the original state of the control, even after the column or row has been moved. So the second time a client-side action occurs, the AJAX request goes to the server and the page & control are built back up again to reflect the first state of the control, not the state after the first column or row was moved.
This problem extends to many implications. For example if we have a client-side/AJAX action to add a new item to the grid, and then a row is dragged, the grid is built server-side with one less item than on the client-side.
And finally & most seriously for my specific example, the actual data source object we are acting upon is stored in the page ViewState. That was a design decision to allow keeping a stateful copy of the manipulated data which can either be committed to DB after many manipulations or discarded if the user backs out. That is very difficult to change.
So, again, I need a way for the page ViewState to be updated on callback after the AJAX method is fired.
If you're already shuffling the ViewState around anyway, you might as well use an UpdatePanel. Its partial postbacks will update the page's ViewState automatically.
Check out this blog post: Tweaking the ICallbackEventHandler and Viewstate. The author seems to be addressing the very situation that you are experiencing:
So when using ICallbackEventHandler you have two obstacles to overcome to have updated state management for callbacks. First is the problem of the read-only viewstate. The other is actually registering the changes the user has made to the page before triggering the callback.
See the blog post for his suggestions on how to solve this. Also check out this forum post which discusses the same problem as well.
I actually found both of those links you provided, but as noted they are simply describing the problem, not solving it. The author of the blog post suggests a workaround by using a different ViewState provider, but unfortunately that isn't a possibility in this case...I really need to leave the particulars of the ViewState alone and just hook on to what is being done out-of-the-box.
I found a fairly elegant solution with Telerik's RadAjaxManager. It works quite nicely. Essentially you register each control which might invoke a postback, and then register each control which should be re-drawn after that postback is performed asynchronously. The RadAjaxManager will update the DOM after the async postback and rewrite the ViewState and all affected controls. After taking a peek in Reflector, it looks a little kludgy under the hood, but it suits my purposes.
I don't understand why you would use a custom control for that, when the built-in ASP.NET AJAX UpdatePanel does the same thing.
It just adds more complexity, gives you less support, and makes it more difficult for others to work on your app.