среда, 11 ноября 2009 г.

Combining ASP.NET AJAX component descriptors

If you have worked with ASP.NET AJAX you know that every instance of ScripCompomentDescriptor created on server side generates startup javascript code at the end of the page. Something like this:

Sys.Application.add_init(function() {
$create(AjaxControlToolkit.DynamicPopulateBehavior, {"PopulateTriggerID":"ctl00_SampleContent_Label1","ServiceMethod":"GetHtml","ServicePath":"/AJAX/AjaxControlToolkit/Samples/DynamicPopulate/DynamicPopulate.aspx","UpdatingCssClass":"dynamicPopulate_Updating","id":"dp1"}, null, null, $get("ctl00_SampleContent_Panel1"));

And the more instances you create the bigger your page size. You should not bother if there are only a few components on your page or when you turn on compression for dynamic content. But if dynamic compression is not an option declaration of dozens of ajax script controls or behaviours can easily twice the page size. ASP.NET AJAX doesn’t have a built-in way of combining multiple ajax component declarations so I had to resort to our old friend Reflection.

All combining logic I’ve put into the class derived from System.Web.UI.ScriptManager. Classes ScriptControlBase and ExtenderControlBase intercept script descriptors registration and register their in our special ScriptManager. The ScriptManager at last possible point, before ASP.NET renders registered startup scripts, combines registered script descriptors, generates necessary javascript code and registers it as startup script. That’s it.

Combined script controls (or behaviours) creation looks like this:


$createMultiple is a function similar to $create, but it creates.. multiple components of a script control/behaviour type.

It takes 5 arguments: name of a script control type to create, array of html elements’ ids, object describing properties setters, events setter and component references setters. Each setter has the name of property (event, component ref) and the value which is always an array. If all script control instances have the same value for the property then the value-array will have only one element, otherwise it is an array where each odd elements is a value and it’s next element is an index (or array of indexes) in html elements array.

Combining is controlled by ScriptManager’s property CombineScriptDescriptors.

A few steps and you can use it with AjaxControlToolkit:

  • Add reference to CombinedDescriptors.dll (or whatever dll you’ve put the classes in) to AjaxControlToolkit project

  • Derive ExtenderControlBase class (AjaxControlToolkit\ExtenderBase\ExtenderControlBase.cs) from my ExtenderControlBase class

  • Derive ScriptControlBase class (AjaxControlToolkit\ExtenderBase\ScriptControlBase .cs) from my ScriptControlBase class

  • Derive ToolkitScriptManager class (AjaxControlToolkit\ToolkitScriptManager\ToolkitScriptManager.cs) from my ToolkitScriptManager class

If you want to test it with AjaxControlToolkit SampleWebSite , change the web site’s trust level to Full (<system.web><trust level="Full"/>), add CombineScriptDescriptors=”true” to the declaration of the ajaxToolkit:ToolkitScriptManager in \App_Themes\SampleSiteTheme\ToolkitScriptManager.skinfile and add the code for $createMultiple function to Common.js in AjaxControlToolkit project.

As Reflection to private types and members is used it may not work in next versions of ASP.NET.

Now it works in .NET 3.5 and .NET 4 Beta 2.


Комментариев нет:

Отправить комментарий