ASP.NET Under the Hood
LANGUAGES:C#
ASP.NETVERSIONS: 2.0
Working with the ASP.NET AJAXControl Toolkit
Integrating the ASP.NET AJAXControl Toolkit into Existing ASP.NET 2.0 Applications
By Daniel N. Egan
Greetings ASP.NET architects and developers! I?m jumpingin to answer some frequently asked questions about the new ASP.NET AJAX ControlToolkit. Enjoy!
Q. I?ve seen a few sessions on Microsoft?s ASP.NET AJAX(formerly code-named ?Atlas?) and really like the cool stuff implemented in theASP.NET AJAX Control Toolkit. I?ve been able to create a new AJAX Web site andplay with the AJAX Control Toolkit sample Web site, but how can I incorporatethese tools into my current ASP.NET 2.0 applications?
A. Whenever new tools or technologies hit the market, developersare always eager to implement all the cool new features. But because mostsample applications are built using clean, from-the-ground-up implementations,it can be challenging to include these new features in your currentapplication.
In this article, we?ll walk through the things necessaryto add the ASP.NET AJAX framework and the AJAX Toolkit Controls to yourexisting ASP.NET 2.0 Web applications. First I?ll show you the files andconfiguration settings you need, then I?ll spice up an existing application byadding to a standard GridView control a floating child data panel with a dropshadow (see Figure 1).
Figure 1: A floating child grid.
Quick ASP.NET AJAXOverview
Components behind AJAX have been around since 1999, whenthe XmlHttpRequest object hit the scene ? but the term AJAX was not used untilearly 2005 when Jesse James Garrett of Adaptive Path coined the term in hisarticle ?Ajax: A New Approach to Web Applications?. AJAXitself is not a technology; instead, it is an acronym that describes a group oftechnologies (CSS, DOM, JavaScript, JSON, XmlHttpRequest) used to createdynamic Web pages. In the past, these technologies were cobbled together byhand and would test the patience of even the most dedicated coder. One of thereasons AJAX has taken hold of thedevelopment world is because a few venders (some open source, some not) havepackaged these components into easy to use frameworks. In this article, we?lluse Microsoft?s ASP.NET AJAX framework and the ASP.NET AJAX Control Toolkit (read:AJAX-ized user controls) to enhance an existing ASP.NET 2.0 application. Thisarticle will not cover the ASP.NET AJAX framework internals, but you do need toknow what to download and install.
What to Download
The AJAX Control Toolkit sits on top of ASP.NET AJAX, eachdownloaded separately. The official site for all things AJAX(Microsoft?s AJAX, anyway) is http://ajax.asp.net.From this site you can download the ASP.NET AJAX installer,ASPAJAXExtSetup.msi. This adds a new set of project templates and new Toolboxcontrols accessible to Web site projects in Visual Studio or Visual WebDeveloper (see Figure 2).
Figure 2: The AJAXExtensions tab.
After installing ASP.NET AJAX, download the ASP.NET AJAXControl Toolkit. This download also is on Microsoft?s AJAXsite (these controls are open source, so you can download them directly fromCodePlex: http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=AtlasControlToolkit).You can download the controls with or without the source code, but if you areplanning to build your own controls, want to contribute to the project, or justwant to poke around the code, the source code version is valuable.
Setting Up the ASP.NET AJAXControl Toolkit
The ASP.NET AJAX Control Toolkit doesn?t provide aninstaller to automatically add controls to the Toolbox. To install the toolkityou must first unzip the files to any file directory of your choosing. Then,from Visual Studio or Visual Web Developer, create a new tab in the Toolbox.You can create a tab by right-clicking in an empty space of the toolbox andselecting Add Tab. I chose to name my tab AJAX Toolkit (see Figure 3). Aftercreating this tab, right-click beneath the tab heading and select Choose Items.From the dialog presented browse to the location where you unzipped the toolkitfiles and find the Sample Website\Bin folder. Click on theAjaxControlToolkit.dll and click OK. This will add all the AJAXcontrols to your toolbox. Now you can use these controls in your ASP.NET 2.0projects!
Figure 3: The AJAXToolkit tab.
Modifying the web.config
Because ASP.NET AJAX is a new technology (Beta 1 at this writing),it is not fully integrated into the base configuration files of .NET 2.0. As aresult, several new configuration entries must be added to an AJAX-enabled site?sweb.config. To incorporate ASP.NET AJAX into an existing application, you havesome options. Your choice will depend on the amount of information currentlystored in the web.config.
The first option is by far the easiest option. If yourweb.config has very few settings, such as connection strings and otherapplication settings, you can use the sample web.config file that comes withthe ASP.NET AJAX Control Toolkit. Merging your existing configuration settingsinto the toolkit?s configuration file takes a mere three steps:
- Rename your current web.config file toweb.configold
- Copy the web.config file found in <unzippedlocation>\ AjaxControlToolkit-NoSource\SampleWebSite
- Copy any information needed from web.configoldto the newly copied web.config file
The second option is to manually add the requiredconfiguration settings. Because this discussion is related specifically toAJAX-enabling existing applications, you are likely to have a slew of settingsin the web.config file, which further complicates the configuration merge. Moreimportantly, most developers want to know what settings are required in depth,so I?ll take you through the steps of merging the configuration settings and,along the way, describe what you are adding.
The .NET 2.0 Framework provides a base set of supportedconfiguration sections in the machine.config and web.config files from C:\WINDOWS\Microsoft.Net\Framework\<currentversion> \CONFIG. Because ASP.NET AJAX is currently beta software, you mustadd the new section groups to the configuration file. To achieve this, add <configSections>,<sectionGroup>, and <section> tags to our configuration files? <configuration>section (see Figure 4). This will define our configuration sections and declarethe namespaces needed for ASP.NET AJAX to work in your application. We?llfurther define these sections farther down in the web.config file.
<configuration>
<configSections>
<sectionGroupname="microsoft.web"
type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup,
Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35">
<sectionGroupname="scripting"
type="Microsoft.Web.Configuration.ScriptingSectionGroup,
Microsoft.Web.Extensions, Version=1.0.61025.0,Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<sectionGroupname="webServices"
type="Microsoft.Web.Configuration.ScriptingWebServicesSectionGroup,
Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35">
<sectionname="jsonSerialization"
type="Microsoft.Web.Configuration.ScriptingJsonSerializationSection,
Microsoft.Web.Extensions, Version=1.0.61025.0,Culture=neutral,
PublicKeyToken=31bf3856ad364e35"requirePermission="false"/>
<section name="profileService"
type="Microsoft.Web.Configuration.ScriptingProfileServiceSection,
Microsoft.Web.Extensions, Version=1.0.61025.0,Culture=neutral,
PublicKeyToken=31bf3856ad364e35"requirePermission="false"/>
<sectionname="authenticationService"
type="Microsoft.Web.Configuration.ScriptingAuthenticationServiceSection,
Microsoft.Web.Extensions, Version=1.0.61025.0,Culture=neutral,
PublicKeyToken=31bf3856ad364e35"requirePermission="false"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
Figure 4: You mustadd new section groups to the configuration file.
Next, you must add some items to the <pages> sectionof the web.config file. Specifically, we need to add <controls> and <tagMapping>sections (see Figure 5). This will allow us to add AJAXtags to our pages without having to reference the assemblies in each oneindividually.
<pages>
<controls>
<addtagPrefix="asp" namespace="Microsoft.Web.UI"assembly="Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
<add tagPrefix="asp"namespace="Microsoft.Web.UI.Controls"assembly="Microsoft.Web.Extensions,
Version=1.0.61025.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</controls>
<tagMapping>
<addtagType="System.Web.UI.WebControls.CompareValidator"
mappedTagType="Microsoft.Web.UI.Compatibility.CompareValidator,
Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<addtagType="System.Web.UI.WebControls.CustomValidator"
mappedTagType="Microsoft.Web.UI.Compatibility.CustomValidator,Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
<addtagType="System.Web.UI.WebControls.RangeValidator"
mappedTagType="Microsoft.Web.UI.Compatibility.RangeValidator,Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
<addtagType="System.Web.UI.WebControls.RegularExpressionValidator"
mappedTagType="Microsoft.Web.UI.Compatibility.RegularExpressionValidator,
Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<addtagType="System.Web.UI.WebControls.RequiredFieldValidator"
mappedTagType="Microsoft.Web.UI.Compatibility.RequiredFieldValidator,
Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<addtagType="System.Web.UI.WebControls.ValidationSummary"
mappedTagType="Microsoft.Web.UI.Compatibility.ValidationSummary,Microsoft.Web.Extensions,
Version=1.0.61025.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</tagMapping>
</pages>
Figure 5: Adding <controls>and <tagMapping> sections.
The next section you need to configure is the <compilation>section. This section will already exist in your file and will be formattedwith the opening and closing tag on the same line:
<compilation debug="false" strict="false"explicit="true" />
We?ll need to switch to the separate open/close tag formatso that we can add our assembly tags to the section:
<compilation debug="true">
<assemblies>
<addassembly="Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<addassembly="System.Design,
Version=2.0.0.0,Culture=neutral,
PublicKeyToken=B03F5F7F11D50A3A"/>
<addassembly="System.Windows.Forms,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
Continuing the modifications, you must add <HttpHandlers>and <HttpModules> sections (see Figure 6). These will go right under the </compilation>end tag. Notice that in the HttpHandler section you first remove the defaultmapping for the *.asmx Web services extension. This is so the ASP.NET pipelinecan instead map *.asmx files to a handler associated with ASP.NET AJAX. Youthen add the HttpModules necessary for Compression and Scripting.
<httpHandlers>
<removeverb="*" path="*.asmx"/>
<add verb="*" path="*.asmx"validate="false"
type="Microsoft.Web.Script.Services.ScriptHandlerFactory,Microsoft.Web.Extensions,
Version=1.0.61025.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpHandlers>
<httpModules>
<addname="WebResourceCompression"
type="Microsoft.Web.Handlers.WebResourceCompressionModule,Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<addname="ScriptModule" type="Microsoft.Web.UI.ScriptModule,Microsoft.Web.Extensions,
Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
Figure 6: Adding <HttpHandlers>and <HttpModules> sections.
Finally, you must define the sections previously describedin the <sectionGroup> tags. Between the ending <system.web> tag andbefore the ending <configuration/> tag, add the code shown in Figure 7.
<microsoft.web>
<scripting>
<webServices>
<!-- Uncomment this line to customizemaxJsonLength
and add a custom converter -->
<!--
<jsonSerializationmaxJsonLength="500">
<converters>
<addname="ConvertMe"type="Acme.SubAcme.ConvertMeTypeConverter"/>
</converters>
</jsonSerialization>
-->
<!-- Uncommentthis line to enable the authentication
service. IncluderequireSSL="true" if appropriate. -->
<!--
<authenticationServiceenabled="true" requireSSL = "true|false"/>
-->
<!-- Uncommentthese lines to enable the profile
service. To allow profile properties to be retrieved
and modified inAtlas applications, you need to add
each property nameto the setProperties and
getPropertiesattributes. -->
<!--
<profileServiceenabled="true"
setProperties="propertyname1,propertyname2"
getProperties="propertyname1,propertyname2" />
-->
</webServices>
</scripting>
</microsoft.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<addname="ScriptModule" preCondition="integratedMode"
type="Microsoft.Web.UI.ScriptModule,
Microsoft.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<removename="WebServiceHandlerFactory-ISAPI-2.0"/>
<addname="ScriptHandlerFactory" verb="*"path="*.asmx"
preCondition="integratedMode"type=
"Microsoft.Web.Script.Services.ScriptHandlerFactory,
Microsoft.Web.Extensions,Version=1.0.61025.0,
Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
</handlers>
</system.webServer>
Figure 7: Definethe sections described in the <sectionGroup> tags.
The modifications made to the web.config may seem excessivejust to run ASP.NET AJAX, but remember that most of this information shouldeventually be added to the machine-level web.config and will be included in allyour ASP.NET projects by default. At this point, your set-up is complete; nowyou can get to the fun part.
Enhancing the DataGrid
Remember, we want to use some of the ASP.NET AJAX ControlToolkit controls in a way that will be useful to current ASP.NET applications.Because most current applications make use of the GridView control to presentrelevant data to the user, it?s a good exercise to allow users to view childdata in a hovering window, complete with its own shadow. To do this, we?ll usetwo controls from the AJAX Control Toolkit: HoverMenuExtender andDropShadowExtender.
The sample application uses a dataset as the DAL (Data AccessLayer) and an ObjectDataSource to hydrate the GridView, but the following codewill work with whatever DAL you are using.
To begin, add a <ScriptManager> to the page. The <ScriptManager>is the workhorse of ASP.NET AJAX; it manages the AJAX Extensions components,partial page rendering, client requests, and server responses on ASP.NET serverpages. Adding one of these to your page will give you the AJAX Extensions tab plumbingneeded to use the controls (again, see Figure 2).
When you installed the ASP.NET AJAX beta (Or CPT), itadded an AJAX Extensions tab to your toolbox. Drag a ScriptManager object fromthe toolbox onto your Web form. The ScriptManager must be placed inside the <form>tag. If you are using MasterPages, make sure that it is within the <content>tag:
<asp:ScriptManager id="MasterScriptManager"runat="Server">
</asp:ScriptManager>
The ScriptManager can also be placed on the MasterPage,but, depending on your configuration, it would then require the use of aScriptManagerProxy on each individual page. We?ll be keeping it simple; onlyuse a <ScriptManager>. Once you place the ScriptManager on the page, allyou need to do for the simple example is set its id attribute.
To control the visibility of the pop-up window, you?llneed to set up a column that will be used to bring up the floating childwindow. Because this column will not be bound to data in the database, I?ll usea template column. Inside the ItemTemplate, wrap the text in a panel. This willbe referenced by the AJAX control:
<asp:TemplateField>
<ItemTemplate>
<asp:PanelID="ColumnPanel" runat="server">
View Detail
</asp:Panel>
Next, add another panel to the page. This will hold thechild data that will be shown by the hover menu. Notice we?re using a GridViewto display the child data. This is done for simplicity. The child data can beshown in any way you choose. The important thing to notice in this section isthat we are wrapping the GridView in another panel that will allow it to beaccessed by our AJAX control (seeFigure 8).
<asp:Panel ID="PopupPanel"runat="server" CssClass="PopupPanel">
<divstyle="border: 1px outset white; padding: 10px;background-color:White" >
<asp:GridViewID="GridView2" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundFieldDataField="OrderID" HeaderText="OrderID"SortExpression="OrderID" />
<asp:BoundFieldDataField="CompanyName" HeaderText="CompanyName" />
<asp:BoundFieldDataField="ProductName" HeaderText="ProductName" />
<asp:BoundFieldDataField="UnitPrice" HeaderText="UnitPrice" />
<asp:BoundFieldDataField="Quantity" HeaderText="Quantity" />
</Columns>
</asp:GridView>
Figure 8: Wrap theGridView in another panel that will allow it to be accessed by our AJAXcontrol.
To fill the child data, use a second ObjectDataSouce topopulate the child GridView (see Figure 9). Notice that the DataSource is usinga SelectParameter called OrderID. We?ll be dynamically populating this parameteras the parent GridView is being rendered.
<asp:ObjectDataSource ID="ObjectDataSource2"runat="server"
OldValuesParameterFormatString="original_{0}"
OnSelecting="ObjectDataSource2_Selecting"
SelectMethod="GetOrderDetailData"
TypeName="OrdersTableAdapters.Order_DetailsTableAdapter">
<SelectParameters>
<asp:ParameterName="OrderID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
</div>
</asp:Panel>
Figure 9: Use asecond ObjectDataSouce to populate the child GridView.
Finally, after setting up both panels, simply drag theASP.NET AJAX Controls onto the form and set their properties. First, addHoverMenuExtender. The most important properties for this control arePopupControlID and TargetControlID. These are set to the panels createdearlier. When you hover over ColumnPanel, the control will show the contents ofPopupPanel in a hovering window:
<ajaxToolkit:HoverMenuExtender ID="childHover"runat="Server"
PopDelay="25"
PopupControlID="PopupPanel"
PopupPosition="Right"
TargetControlID="ColumnPanel">
</ajaxToolkit:HoverMenuExtender>
Just to spice up HoverMenuExtender a bit, let?s useanother ASP.NET AJAX Control to add a drop-shadow effect to the pop-up window. Simplydrag the DropShadowExtender onto your Web form and set its TargetControlIDequal to our PopupPanel. You can modify its effect by adjusting the Opacity orRounded properties:
<ajaxToolkit:DropShadowExtender
ID="DropShadowExtender1"runat="server"
TargetControlID="PopupPanel"
Opacity=".7"
Rounded="false"
TrackPosition="true">
</ajaxToolkit:DropShadowExtender>
</ItemTemplate>
</asp:TemplateField>
The last thing you must do to complete the project is addsome code to set the SelectParameter of the ChildDataSource. This can be donein-line or in the code-behind file. For simplicity, we?ll add to the top of the.aspx page the script shown in Figure 10.
<script runat="server">
string OrderID;
protected voidPage_Load(object sender, EventArgs e)
{
Page.DataBind();
}
protected voidObjectDataSource2_Selecting(object sender,
ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["OrderID"] = OrderID;
}
protected voidGridView1_RowCreated(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType ==DataControlRowType.DataRow)
{
OrderID =DataBinder.Eval(e.Row.DataItem,
"OrderID").ToString();
}
}
</script>
Figure 10: Add thisto the top of the .aspx page.
I use the GridView?s RowCreated event to retrieve theOrderID for the row and then use it to populate the DataSource for the childgrid?s InputParameter during the Selecting event. I also need to bind thecontrols on the page during the Page_Load event because of some breakingchanges in Beta 1 of the controls. This should become unnecessary at the nextrelease. You should now be able to view your new floating child data.
Conclusion
Whether you are creating a company intranet or building a Webportal, you?ll find the ASP.NET AJAX Framework, and specifically the AJAXControl Toolkit, a welcome addition to your developer toolset, enabling you tobuild better and more dynamic Web sites. As you can see, once you have yourweb.config set up correctly, you?ll be able to add AJAX Controls to your pagesby dragging controls and setting some simple properties.
If you have additional questions about this or otherASP.NET topics, drop a line to mailto:underthehood@aspnetpro.com.Thanks for reading!
Daniel Egan, anMCT, MCSD, and Microsoft ASP.NET MVP, has held a variety of positions in theinformation technology and engineering fields before starting EEPros Inc. (http://www.EEPros.com),where he serves as Chief Architect and Sr. Trainer in charge of custom clienttraining. In addition to his development work, Daniel teaches a .NETCertification course and serves on the .NET Advisory board at California State University,Fullerton. He is also the co-founderof the SoCalDotNet Developers Group. Daniel is a frequent speaker andconference presenter, has written several articles, and is the author of Building Websites with VB.NET and DotNetNuke 3.0(Packt Publishing). To find out more about Daniel, visit his blogs: Dot Net Doc(http://www.DotNetDoc.com), a .NET andDNN developer resource blog, or ThePatternMan (http://www.ThePatternMan.com), whichfocuses on Design Patterns in .NET.