ASP.NET Under the Hood

LANGUAGES: C#

ASP.NET VERSIONS: 2.0

 

Working with the ASP.NET AJAX Control Toolkit

Integrating the ASP.NET AJAX Control Toolkit into Existing ASP.NET 2.0 Applications

 

By Daniel N. Egan

 

Greetings ASP.NET architects and developers! I m jumping in to answer some frequently asked questions about the new ASP.NET AJAX Control Toolkit. 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 the ASP.NET AJAX Control Toolkit. I ve been able to create a new AJAX Web site and play with the AJAX Control Toolkit sample Web site, but how can I incorporate these tools into my current ASP.NET 2.0 applications?

 

A. Whenever new tools or technologies hit the market, developers are always eager to implement all the cool new features. But because most sample applications are built using clean, from-the-ground-up implementations, it can be challenging to include these new features in your current application.

 

In this article, we ll walk through the things necessary to add the ASP.NET AJAX framework and the AJAX Toolkit Controls to your existing ASP.NET 2.0 Web applications. First I ll show you the files and configuration settings you need, then I ll spice up an existing application by adding to a standard GridView control a floating child data panel with a drop shadow (see Figure 1).

 


Figure 1: A floating child grid.

 

Quick ASP.NET AJAX Overview

Components behind AJAX have been around since 1999, when the XmlHttpRequest object hit the scene but the term AJAX was not used until early 2005 when Jesse James Garrett of Adaptive Path coined the term in his article Ajax: A New Approach to Web Applications . AJAX itself is not a technology; instead, it is an acronym that describes a group of technologies (CSS, DOM, JavaScript, JSON, XmlHttpRequest) used to create dynamic Web pages. In the past, these technologies were cobbled together by hand and would test the patience of even the most dedicated coder. One of the reasons AJAX has taken hold of the development world is because a few venders (some open source, some not) have packaged these components into easy to use frameworks. In this article, we ll use 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. This article will not cover the ASP.NET AJAX framework internals, but you do need to know what to download and install.

 

What to Download

The AJAX Control Toolkit sits on top of ASP.NET AJAX, each downloaded 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 Toolbox controls accessible to Web site projects in Visual Studio or Visual Web Developer (see Figure 2).

 


Figure 2: The AJAX Extensions tab.

 

After installing ASP.NET AJAX, download the ASP.NET AJAX Control Toolkit. This download also is on Microsoft s AJAX site (these controls are open source, so you can download them directly from CodePlex: http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=AtlasControlToolkit). You can download the controls with or without the source code, but if you are planning to build your own controls, want to contribute to the project, or just want to poke around the code, the source code version is valuable.

 

Setting Up the ASP.NET AJAX Control Toolkit

The ASP.NET AJAX Control Toolkit doesn t provide an installer to automatically add controls to the Toolbox. To install the toolkit you 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 and selecting Add Tab. I chose to name my tab AJAX Toolkit (see Figure 3). After creating this tab, right-click beneath the tab heading and select Choose Items. From the dialog presented browse to the location where you unzipped the toolkit files and find the Sample Website\Bin folder. Click on the AjaxControlToolkit.dll and click OK. This will add all the AJAX controls to your toolbox. Now you can use these controls in your ASP.NET 2.0 projects!

 


Figure 3: The AJAX Toolkit 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 a result, several new configuration entries must be added to an AJAX-enabled site s web.config. To incorporate ASP.NET AJAX into an existing application, you have some options. Your choice will depend on the amount of information currently stored in the web.config.

 

The first option is by far the easiest option. If your web.config has very few settings, such as connection strings and other application settings, you can use the sample web.config file that comes with the ASP.NET AJAX Control Toolkit. Merging your existing configuration settings into the toolkit s configuration file takes a mere three steps:

  • Rename your current web.config file to web.configold
  • Copy the web.config file found in <unzipped location>\ AjaxControlToolkit-NoSource\SampleWebSite
  • Copy any information needed from web.configold to the newly copied web.config file

 

The second option is to manually add the required configuration settings. Because this discussion is related specifically to AJAX-enabling existing applications, you are likely to have a slew of settings in the web.config file, which further complicates the configuration merge. More importantly, 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 supported configuration sections in the machine.config and web.config files from C:\WINDOWS\Microsoft.Net\Framework\<current version> \CONFIG. Because ASP.NET AJAX is currently beta software, you must add 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 declare the namespaces needed for ASP.NET AJAX to work in your application. We ll further define these sections farther down in the web.config file.

 

<configuration>

 <configSections>

     <sectionGroup name="microsoft.web"

    type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup,

     Microsoft.Web.Extensions,

     Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">

    <sectionGroup name="scripting"

     type="Microsoft.Web.Configuration.ScriptingSectionGroup,

    Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,

    PublicKeyToken=31bf3856ad364e35">

   <sectionGroup name="webServices"

     type="Microsoft.Web.Configuration.ScriptingWebServicesSectionGroup,

     Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,

     PublicKeyToken=31bf3856ad364e35">

        <section name="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"/>

      <section name="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 must add new section groups to the configuration file.

 

Next, you must add some items to the <pages> section of the web.config file. Specifically, we need to add <controls> and <tagMapping> sections (see Figure 5). This will allow us to add AJAX tags to our pages without having to reference the assemblies in each one individually.

 

<pages>

  <controls>

    <add tagPrefix="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>

    <add tagType="System.Web.UI.WebControls.CompareValidator"

       mappedTagType="Microsoft.Web.UI.Compatibility.CompareValidator,

       Microsoft.Web.Extensions,   Version=1.0.61025.0, Culture=neutral,

       PublicKeyToken=31bf3856ad364e35"/>

    <add tagType="System.Web.UI.WebControls.CustomValidator"

       mappedTagType="Microsoft.Web.UI.Compatibility.CustomValidator, Microsoft.Web.Extensions,

       Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

    <add tagType="System.Web.UI.WebControls.RangeValidator"

       mappedTagType="Microsoft.Web.UI.Compatibility.RangeValidator, Microsoft.Web.Extensions,

       Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

    <add tagType="System.Web.UI.WebControls.RegularExpressionValidator"

       mappedTagType="Microsoft.Web.UI.Compatibility.RegularExpressionValidator,

       Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,

       PublicKeyToken=31bf3856ad364e35"/>

    <add tagType="System.Web.UI.WebControls.RequiredFieldValidator"

       mappedTagType="Microsoft.Web.UI.Compatibility.RequiredFieldValidator,

       Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral,

       PublicKeyToken=31bf3856ad364e35"/>

   <add tagType="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 formatted with 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 format so that we can add our assembly tags to the section:

 

<compilation debug="true">

        <assemblies>

 <add assembly="Microsoft.Web.Extensions,

   Version=1.0.61025.0, Culture=neutral,

   PublicKeyToken=31bf3856ad364e35"/>

 <add assembly="System.Design,

  Version=2.0.0.0, Culture=neutral,

   PublicKeyToken=B03F5F7F11D50A3A"/>

    <add assembly="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 default mapping for the *.asmx Web services extension. This is so the ASP.NET pipeline can instead map *.asmx files to a handler associated with ASP.NET AJAX. You then add the HttpModules necessary for Compression and Scripting.

 

<httpHandlers>

 <remove verb="*" 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>

 <add name="WebResourceCompression"

             type="Microsoft.Web.Handlers.WebResourceCompressionModule, Microsoft.Web.Extensions,

             Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

 <add name="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 described in the <sectionGroup> tags. Between the ending <system.web> tag and before the ending <configuration/> tag, add the code shown in Figure 7.

 

<microsoft.web>

 <scripting>

   <webServices>

     <!-- Uncomment this line to customize maxJsonLength

       and add a custom converter -->

     <!--

   <jsonSerialization maxJsonLength="500">

     <converters>

       <add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/>

     </converters>

   </jsonSerialization>

   -->

     <!-- Uncomment this line to enable the authentication

      service. Include requireSSL="true" if appropriate. -->

     <!--

     <authenticationService enabled="true" requireSSL = "true|false"/>

      -->

     <!-- Uncomment these lines to enable the profile

       service. To allow profile properties to be retrieved

      and modified in Atlas applications, you need to add

      each property name to the setProperties and

      getProperties attributes. -->

     <!--

   <profileService enabled="true"

    setProperties="propertyname1,propertyname2"

    getProperties="propertyname1,propertyname2" />

   -->

   </webServices>

 </scripting>

</microsoft.web>

<system.webServer>

 <validation validateIntegratedModeConfiguration="false"/>

 <modules>

   <add name="ScriptModule" preCondition="integratedMode"

    type="Microsoft.Web.UI.ScriptModule,

    Microsoft.Web.Extensions, Version=1.0.61025.0,

     Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

 </modules>

 <handlers>

   <remove name="WebServiceHandlerFactory-ISAPI-2.0"/>

   <add name="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: Define the sections described in the <sectionGroup> tags.

 

The modifications made to the web.config may seem excessive just to run ASP.NET AJAX, but remember that most of this information should eventually be added to the machine-level web.config and will be included in all your ASP.NET projects by default. At this point, your set-up is complete; now you can get to the fun part.

 

Enhancing the DataGrid

Remember, we want to use some of the ASP.NET AJAX Control Toolkit controls in a way that will be useful to current ASP.NET applications. Because most current applications make use of the GridView control to present relevant data to the user, it s a good exercise to allow users to view child data in a hovering window, complete with its own shadow. To do this, we ll use two controls from the AJAX Control Toolkit: HoverMenuExtender and DropShadowExtender.

 

The sample application uses a dataset as the DAL (Data Access Layer) and an ObjectDataSource to hydrate the GridView, but the following code will 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 server pages. Adding one of these to your page will give you the AJAX Extensions tab plumbing needed to use the controls (again, see Figure 2).

 

When you installed the ASP.NET AJAX beta (Or CPT), it added an AJAX Extensions tab to your toolbox. Drag a ScriptManager object from the 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 a ScriptManagerProxy on each individual page. We ll be keeping it simple; only use a <ScriptManager>. Once you place the ScriptManager on the page, all you need to do for the simple example is set its id attribute.

 

To control the visibility of the pop-up window, you ll need to set up a column that will be used to bring up the floating child window. Because this column will not be bound to data in the database, I ll use a template column. Inside the ItemTemplate, wrap the text in a panel. This will be referenced by the AJAX control:

 

<asp:TemplateField>

 <ItemTemplate>

   <asp:Panel ID="ColumnPanel" runat="server">

      View Detail

   </asp:Panel>

 

Next, add another panel to the page. This will hold the child data that will be shown by the hover menu. Notice we re using a GridView to display the child data. This is done for simplicity. The child data can be shown in any way you choose. The important thing to notice in this section is that we are wrapping the GridView in another panel that will allow it to be accessed by our AJAX control (see Figure 8).

 

<asp:Panel ID="PopupPanel" runat="server"  CssClass="PopupPanel">

 <div style="border: 1px outset white; padding: 10px; background-color:White" >

 <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="false">

   <Columns>

      <asp:BoundField DataField="OrderID" HeaderText="OrderID" SortExpression="OrderID" />

      <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" />

      <asp:BoundField DataField="ProductName" HeaderText="ProductName" />

      <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" />

      <asp:BoundField DataField="Quantity" HeaderText="Quantity" />

   </Columns>

 </asp:GridView>

Figure 8: Wrap the GridView in another panel that will allow it to be accessed by our AJAX control.

 

To fill the child data, use a second ObjectDataSouce to populate the child GridView (see Figure 9). Notice that the DataSource is using a SelectParameter called OrderID. We ll be dynamically populating this parameter as 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:Parameter Name="OrderID" Type="Int32" />

    </SelectParameters>

 </asp:ObjectDataSource>

 </div>

 </asp:Panel>

Figure 9: Use a second ObjectDataSouce to populate the child GridView.

 

Finally, after setting up both panels, simply drag the ASP.NET AJAX Controls onto the form and set their properties. First, add HoverMenuExtender. The most important properties for this control are PopupControlID and TargetControlID. These are set to the panels created earlier. When you hover over ColumnPanel, the control will show the contents of PopupPanel 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 use another ASP.NET AJAX Control to add a drop-shadow effect to the pop-up window. Simply drag the DropShadowExtender onto your Web form and set its TargetControlID equal to our PopupPanel. You can modify its effect by adjusting the Opacity or Rounded 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 add some code to set the SelectParameter of the ChildDataSource. This can be done in-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 void Page_Load(object sender, EventArgs e)

 {

     Page.DataBind();

 }

 protected void ObjectDataSource2_Selecting(object sender,

   ObjectDataSourceSelectingEventArgs e)

 {

     e.InputParameters["OrderID"] = OrderID;

 }

 protected void GridView1_RowCreated(object sender,

   GridViewRowEventArgs e)

 {

     if (e.Row.RowType == DataControlRowType.DataRow)

     {

         OrderID = DataBinder.Eval(e.Row.DataItem,

           "OrderID").ToString();

     }

 }

</script>

Figure 10: Add this to the top of the .aspx page.

 

I use the GridView s RowCreated event to retrieve the OrderID for the row and then use it to populate the DataSource for the child grid s InputParameter during the Selecting event. I also need to bind the controls on the page during the Page_Load event because of some breaking changes in Beta 1 of the controls. This should become unnecessary at the next release. You should now be able to view your new floating child data.

 

Conclusion

Whether you are creating a company intranet or building a Web portal, you ll find the ASP.NET AJAX Framework, and specifically the AJAX Control Toolkit, a welcome addition to your developer toolset, enabling you to build better and more dynamic Web sites. As you can see, once you have your web.config set up correctly, you ll be able to add AJAX Controls to your pages by dragging controls and setting some simple properties.

 

If you have additional questions about this or other ASP.NET topics, drop a line to editors@devproconnections.com. Thanks for reading!

 

Daniel Egan, an MCT, MCSD, and Microsoft ASP.NET MVP, has held a variety of positions in the information 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 client training. In addition to his development work, Daniel teaches a .NET Certification course and serves on the .NET Advisory board at California State University, Fullerton. He is also the co-founder of the SoCalDotNet Developers Group. Daniel is a frequent speaker and conference 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 and DNN developer resource blog, or ThePatternMan (http://www.ThePatternMan.com), which focuses on Design Patterns in .NET.