# ASP.NET AJAX

## Introduction

Spring's ASP.NET AJAX integration allows for a plain .NET object (PONO), 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.

## 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.

### Exposing Web Services

The `WebServiceExporter` combined with the new HTTP handler exposes PONOs 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.

### 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);
    }