Chapter 23. ASP.NET AJAX

23.1. Introduction

Spring's ASP.NET AJAX integration allows for a plain CLR object (POCO), that is one that doesn't have any attributes or special base classes, to be exported as a web service, configured via dependency injection, 'decorated' by applying AOP, and then exposed to client side JavaScript.

23.2. Web Services

Spring.NET, and particularly Spring.Web, improved support for web services in .NET with the WebServiceExporter. Exporting of an ordinary plain .NET object as a web service is achieved by registering a custom implementation of the WebServiceHandlerFactory class as the HTTP handler for *.asmx requests.

Microsoft ASP.NET AJAX introduced a new HTTP handler System.Web.Script.Services.ScriptHandlerFactory to allow a Web Service to be invoked from the browser by using JavaScript.

Spring's integration allows for both Spring.Web and ASP.NET AJAX functionality to be used together by creating a new HTTP handler.

23.2.1. Exposing Web Services

The WebServiceExporter combined with the new HTTP handler exposes POCOs as Web Services in your ASP.NET AJAX application.

In order for a Web service to be accessed from script, the WebServiceExporter should decorate the Web Service class with the ScriptServiceAttribute. The code below is taken from the sample application Spring.Web.Extensions.Sample, aka the 'AJAX' shortcut in the installation. :

<object id="ContactWebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
  <property name="TargetName" value="ContactService"/>
  <property name="Namespace" value="http://Spring.Examples.Atlas/ContactService"/>
  <property name="Description" value="Contact Web Services"/>
  <property name="TypeAttributes">
    <list>
      <object type="System.Web.Script.Services.ScriptServiceAttribute, System.Web.Extensions"/>
    </list>
  </property>
</object>
          
        

All that one needs to do in order to use the WebServiceExporter is:

1. Configure the Web.config file of your ASP.NET AJAX application as a Spring.Web application.

<sectionGroup name="spring">
  <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
</sectionGroup>
        
        

<spring>
  <context>
    <resource uri="~/Spring.config"/>
  </context>
</spring>
        
        

2. Register the HTTP handler and the Spring HttpModule under the system.web section.

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

<httpModules>
  <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  <add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</httpModules>
        
        

3. Register the HTTP handler and the Spring HttpModule under system.webServer section.

<modules>
  <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  <add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</modules>
<handlers>
  <remove name="WebServiceHandlerFactory-Integrated" />
  <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" 
       type="Spring.Web.Script.Services.ScriptHandlerFactory, Spring.Web.Extensions"/>
  <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
       type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.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=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>
        
        

You can find a full Web.config file in the example that comes with this integration.

23.2.2. Calling Web Services by using JavaScript

A proxy class is generated for each Web Service. Calls to Web Services methods are made by using this proxy class. When using the WebServiceExporter, the name of the proxy class is equal to the WebServiceExporter's id.

// This function calls the Contact Web service method 
// passing simple type parameters and the callback function  
function GetEmails(prefix, count)
{
    ContactWebService.GetEmails(prefix, count, GetEmailsOnSucceeded);
}