How Do I? – AJAX


I have been seeing a lot of people asking how they get AJAX working in their site. They can get a sample site up and running, but when they begin dropping AJAX in their own site, it fails.

The error encountered here is concerns the AJAX controls not being recognized and can be fixed rather easily by opening your test project and doing a bit of copying. I am first going to focus on getting the site working. We can then look at other issues.

Migrating Code to Make AJAX work

The first task is getting a current site working.

Copy the <ConfigSections> section

<ConfigSections> contains information necessary to wire up your AJAX application. You will need at least most of these to get things working. It is possible some of these are not important. NOTE: This is a 3.5 AJAX site. The version numbers are different in 2.0.

<configSections>
  <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
      <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
        <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
        <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
        <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
      </sectionGroup>
    </sectionGroup>
  </sectionGroup>
</configSections>

Nearly all of these are needed to get AJAX working. If you do not do JSON, you can drop off the jsonSerialization element, but I see no reason to do this. There are some others you can drop off as well, like the profileService and roleService. Note, however, that doing this really gives you nothing and will force you to add them back in if you ever decide to use these features.

Copy the <assemblies> section

In this section, you are setting up the working bits for the pages by importing the assemblies. There are ways around this (declaring page by page), but this is the easiest.

<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

If you are using additional AJAX bits, you may have other declarations here to copy over.

Copy the <pages> section

This is what allows you to add controls to your page. You can also register on a page by page basis and avoid copying this, but why?

<pages>
  <controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  </controls>
</pages>

Copy the <httpHandlers> and <httpModules> sections

This section makes it possible for AJAX calls to be handled by your application. You will not get a compile error if you do not copy this, but you sure will not get a working application either.

<httpHandlers>
  <remove verb="*" path="*.asmx"/>
  <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
  <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>

Set up for IIS 7?

There are two additional sections you will need if your site is going to IIS 7. These sections do very little for development and can, therefore, be called optional. If you are developing in .NET 3.5, I would copy them anyway.

<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules>
    <remove name="ScriptModule" />
    <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  </modules>
  <handlers>
    <remove name="WebServiceHandlerFactory-Integrated"/>
    <remove name="ScriptHandlerFactory" />
    <remove name="ScriptHandlerFactoryAppServices" />
    <remove name="ScriptResource" />
    <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
         type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
         type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  </handlers>
</system.webServer>

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
      <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
      <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Older Versions of ASP.NET AJAX

What if you are using an older version of ASP.NET AJAX? Simple, copy from a sample web that uses the older version. In general, the version number and possibly the PublicKeyToken are the main thing that will change. There may be a declaration or two not present in the older version, as well. If you copy from a sample site using the older version, however, you should be fine.

Additional AJAX Bits?

Since the 3.5 release, Microsoft has been working on newer extensions, including some AJAX bits. If you are using them, you will have to change the version numbers from 3.5.0.0 to 3.6.0.0. There is also a new section name, but you only need it if you are using dynamic data:

<section name="dynamicData" type="System.Web.DynamicData.DynamicDataControlsSection" requirePermission="false" allowDefinition="MachineToApplication" />

Under assemblies, the same. Change version number and only add the following if using dynamic data:

<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

With extensions, there are additional tags in the pages section, but you only need to add these if you are using the features (dynamic data or silverlight):

<add tagPrefix="asp" namespace="System.Web.UI.SilverlightControls" assembly="System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.DynamicData" assembly="System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" tagName="DynamicFilter" src="~/App_Shared/DynamicDataFields/FilterUserControl.ascx" />

Under <httpHandlers> you only need to change the version numbers. Under <httpModules> you have additional tags, but only if you are using Dynamic Data or MVC:

<add name="DynamicDataModule" type="System.Web.DynamicData.DynamicDataHttpModule, System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Mvc.UrlRoutingModule, System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

Under <system.web.extensions>, there are bits for Dynamic data. You do not have to add these for AJAX only. Finally, the <system.webServer> has additional bits if you are using either Dynamic Data or MVC. The only thing you will change for AJAX alone is the version number.

If you are using the AJAX toolkit, there is a designer tags in the <assemblies> section. Other than that, you are golden.

Summary

It is quite easy to prep an older site for AJAX, if you simply move web.config bits over from a site created as an AJAX site. After copy and paste, the controls should register fine.

I meant to find Scott Guthrie’s older blog entry on this, but have not had the chance. Maybe later? It was in the Atlas timeframe (code name for ASP.NET AJAX), so the bits are older (version numbers different primarily).

Peace and Grace,
Greg

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: