Recently, a friend of mine was picking my brain about the necessary steps for setting up a WCF service that can be invoked from an AJAX client-side script. Prior to .NET 3.5, this wasn't actually supported by ASP.NET AJAX. It was only possible to invoke an ASP.NET web service. Technically, you could still use a WCF service. Unfortunately, it had to be wrapped by an ASP.NET web service. Anyway, this seemed like a good blog post to make in honor of Visual Studio 2008 and .NET 3.5 officially going RTM earlier today!
From WCF's perspective, there is very little additional work required to enable AJAX requests. For the most part, it can actually be enabled via configuration. There is a new endpoint behavior and a new binding that take care of the heavy lifting.
WebScriptEnablingBehavior
This is an endpoint behavior that enables a javascript proxy endpoint. It enables the HTTP programming model for dispatching operations based on a URI templates and provides support for HTTP verb selection (aka RESTful services).
WebHttpBinding
This is a new binding that goes hand in hand with the WebScriptEnablingBehavior. It is required in order for WebScriptEnablingBehavior to function. The binding uses a new message encoder that enables plain old xml (POX) messaging rather than SOAP based messaging. To really leverage the potential of this binding, you need to apply the new WebGet and WebInvoke attributes to the applicable service operations.
Below, I have included a configuration example for an WCF service hosted in IIS to give you a bit of an illustration. However, the same thing can be achieved programmatically (if desired).
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpointBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="WeatherService" behaviorConfiguration="ServiceBehavior">
<endpoint address="" behaviorConfiguration="EndpointBehavior"
binding="webHttpBinding" contract="IWeatherService" />
</service>
</services>
</system.serviceModel>
</configuration>
After enabling AJAX requests, you can generate a javascript proxy for your client by browsing to http://localhost/myWebApp/WeatherService.svc/js (based on the configuration example). You can then use the ASP.NET AJAX ScriptManager to supply a ScriptReference to the javascript proxy:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/WeatherService.js" />
</Scripts>
</asp:ScriptManager>
There is an alternative approach as well. Instead of adding a script reference, you can add a service reference. However, it is important to set the InlineScript attribute to false. WCF services aren't compatible with the InlineScript attribute set to true.
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference InlineScript="false" Path="~/WeatherService.svc" />
</Services>
</asp:ScriptManager>
I have a simple demo that you can download here to get a better idea of the big picture.