Ajax »

[4 Sep 2008 | 0 Comments]

Quick post (which apparently has been sitting in my drafts for a few weeks, woops ;-)): ever had an error looking like this when using an AJAX-intensive webapp? 

Validation of viewstate MAC failed.  If this application is hosted by a Web Farm or cluster, ensure that  configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.

or an "Invalid postback or callback argument"-error, coming from the PageRequestManager or ScriptManager?  And you're not on a Web Farm nor cluster?

In more detail: you get the error ad random, not on all machines, not all the time?  Well, so did we.  As you are well aware, errors that seem to happen at random and only on some machines are quite difficult to debug.  In this case, we had our application installed on a standard W3K-server (virtual server).  When I would surf to the app and use it from my laptop, it worked as it should.  However, when one of my collegues surfed to the same site, she randomly got the above error.

Well, apparently this has got something to do with the ViewState being encrypted: when you encrypt your ViewState, an encrypted ViewState field is added just before the closing of the <form>-tag.  However, when you make a postback before the page is fully rendered, the postback is initiated without this field => thus, throws an error.  You can already imagine why this happens with AJAX (ie, partial postbacks) a bit more often ;-)

Solution is easy: in your web.config, in the <pages>-tag, disable EventValidation (enableeventvalidation="false"), and set the encryptionmode to Never (viewstateencryptionmode="Never").  Problem solved!

One quick word of advice: do not do this if you don't have enough other security checks to make sure your viewstate hasn't been tampered with (or enough validation to make sure this gets caught later on in the app).  Another way around this is to disable your form on every (partial) postback. 

Ajax »

[16 Jul 2008 | 0 Comments]

About 2 weeks ago, Bertrand Le Roy let us know they published a roadmap describing some of the proposed futures they are considering for future AJAX / Control Toolkit released.

I read up on it, and it's quite an interesting read.

One of the most striking features is about client data and UI Templates. At the moment, most people use UpdatePanels to make parts of their page postback-free. However, when using an UpdatePanel typically way too much data is sent back and forth between client and server. Easy to program, sure, but not the most efficient way to design a page and keep the load as low as possible. With the client-side data & template-idea, we get an easy way to consume data (eg, from a service) and bind it to a dataview (grid/repeater/listview I suppose), fully AJAX-ified, without using an UpdatePanel. Net effect: we only ask for the data we want from the service, providing much less overhead.

Some other interesting comments by Dave Ward can be found here.

So, if you're interested in where ASP .NET AJAX is going, and you want to give the team your input, here's your chance!

Ajax »

[8 May 2008 | 1 Comments]

The ASP .NET Treeview control is one of the few controls not natively supported by UpdatePanels. Most of the time, this is not a problem - it already includes a bunch of client-side javascript for checking/unchecking the correct nodes, so most of it is client-side anyway, requiring no annoying postbacks.

However, from time to time you absolutely need it to be in an UpdatePanel. In one of my current projects, we have a modal popup (from the AJAX Control Toolkit) with a customized Treeview (customized as in: it includes lots of custom javascript for checking/unchecking the correct nodes when clicked) in it. A bit of server-side code has to be executed to make sure the correct treenodes are checked when the popup is displayed, so we simply fill the treeview with the correct data from the database, check the correct nodes and enable the modalpopupextender from code-behind. No UpdatePanels involved, works like a charm.

After a while, a problem arose: our customized Treeview can grow to be quite big, containing hundreds and hundreds of child nodes. Meaning: since the popup is enabled/disabled in code-behind, the time for it to display became longer and longer. Instead of seeing the popup when clicking a button, the user had to wait 1-2 seconds for it to display. A "minor" annoyance, definitely something you'd want to get rid of.

So we implemented a lazy loading/load on demand technique: show the modalpopup client-side, and execute some javascript after this to make sure the loading & displaying of the Treeview only starts when the modal popup is already on-screen (more on this technique in a future post), thus providing a much smoother user interface. Problem solved? Hardly.

To make this approach work, we use an UpdatePanel around the treeview inside the modal popup, to make sure we can load only this portion of the page on demand... And UpdatePanels & Treeview-controls don't match. This became painfully obvious when we started to get null-object errors when clicking any treeview-node...

Running through the code in debug obviously didn't clarify much. The problem with the Treeview and UpdatePanel/ScriptManager lies (ao) in the fact that they both use quite some javascript to enable their functionality. In this case even more so, since our customized Treeview contains quite some extra javascript functions. Apparently, the correct scripts for the Treeview aren't loaded when you lazy-load a Treeview that's inside an UpdatePanel. Sigh.

But... surely, the Treeview doesn't use its own collection of javascript functions for each Treeview on a page, right? That would cause way too much overhead, right? This would mean there'd have to be a collection of javascript-functions, inserted by ASP .NET when placing one or more Treeview controls on a page, which could then be used by any Treeview on this page. Right? What would happen if I were to make sure all javascript functions used by a Treeview were loaded by default? Would this solve my problem?

I gave this approach a try: I placed a dummy customized Treeview control on my page, setting its style to display:none. This should make sure all javascript functions are loaded by default, so other Treeview controls should be able to use them.

... and apparently, this did the trick! :-)

I'm still not entirely sure if I'm on the right track here when talking about how javascript is inserted by ASP .NET. But what I am sure of is, when using this approach, our customized Treeview works like a charm, inside an UpdatePanel inside an on-demand-loaded modal popup. Hope it helps! ;-)

Ajax »

[3 Apr 2008 | 0 Comments]

I've been following progress on & have been using the AJAX Control Toolkit more or less since it started maturing in 2006. Over the last year, it has grown into a solid collection of useful, easy-to-implement controls, which are used around the world by most people who are developing AJAX-enabled Microsoft ASP .NET web apps. And those who don't use 'em should ;-)



From time to time however, you run into a feature you absolutely need to have, but which isn't supported by the Toolkit.



One of the requirements for one of the projects I'm working on is being able to show as much tabular data (typically search results) as possible on a page, thus limiting the amount of scrolling required. What we do to reach this goal: we use the CollapsiblePanelExtender on the panel containing the the search criteria. When a user searches for some specific data, the list with criteria is collapsed, leaving more room for the result grid (of course, the user can expand the criteria again & input new ones any time he likes).



At first, we used the CollapsiblePanelExtender for this. One problem: when you collapse or expand a panel, a short animation plays, and there's no out-of-the-box way to turn this off. Though the animations are great, in this specific case it made the page feel a little "sluggish". Seeing I'm a sucker for clean (yet quite glossy), fast & user-friendly webpages, a solution had to be found.



So I created my own version of the CollapsiblePanelExtender, the ExtendedCollapsiblePanelExtender (yes, I AM running out of inspiration when it comes to naming these things ;-)). I added two properties: ShowAnimation & AnimationDuration. Default values are true & 250ms respectively, meaning changing your CollapsiblePanelExtenders to this ExtendedCollapsiblePanelExtenders will not change any behaviour as long as you don't explicitly set the properties to other values.



Obviously, when ShowAnimation is false, the animation doesn't play. This isn't the same as hard-coding the duration to a very low value: when you do that, the animation still gets initialized and still plays, albeit very fast. When you set ShoWAnimation to false, the animation doesn't get initialized and doesn't play at all (saving you quite some execution time).



While I was at it, I added an AnimationDuration-property as well. By default, the animation plays for 250ms - with this new property, you can let it play as short/long as you want.



Using the ExtendedCollapsiblePanelExtender is as easy as using any Toolkit control: just add an assembly reference to your project, register the assembly on the page, and use it like any other control.




ExtendedCollapsiblePanelExtender example



I uploaded the source code of this extender, including a small demo webapp to show you how to use it in your projects. Feel free to have a look at the source (comments are included), modify it, or simply use the extender on your own webapps. Download here, enjoy!



(note: the source is built on .NET 3.5, for use with Visual Studio 2008, using the latest version of the AJAX Control Toolkit (February 2008 version). But if for some reason you need a version for .NET 2.0, you can easily design it using the provided sources.)