Introduction
This is a simple example of an Ajax-Enabled WCF Service (hosted in IIS) that can be consumed using both client-side and server-side code.
I've seen no articles or forum discussions that have properly addressed this topic. I was interested hosting an Ajax-Enabled WCF Service in IIS and consuming that web service using by both client-side and server-side code.
Background
My starting point for this was the following: http://msdn.microsoft.com/en-us/library/bb412167(v=vs.100).aspx
Step 1 - Create a solution and service project
- Add a WCF Service Application project to the solution called FooService
- Delete everything in the service project’s web.config file.
="1.0"
<configuration>
</configuration>
- Create a class file called FooServiceOne.cs
- Replace the code with this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
namespace GooberFoo.FooServices
{
[ServiceContract(Namespace = "GooberFoo.FooServices")]
public interface IFooServiceOne
{
[OperationContract]
double Add(double n1, double n2);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class FooServiceOne : IFooServiceOne
{
public double Add(double n1, double n2)
{
return n1 + n2;
}
}
}
- Create another file called FooServiceOne.svc and past the following code into the file.
<%@ServiceHost
language="C#"
Debug="true"
Service="GooberFoo.FooServices.FooServiceOne"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
%>
- Save and Compile
Step 2 - Host the service is IIS
- Make sure "Enable anonymous access" is checked.
- Make sure "Integrated Windows authentication" is unchecked.
- Test the service by navigating to http://GooberServer:90/FooServiceOne.svc
- The service will be displayed with the message "Metadata publishing for this service is currently disabled."
Step 3 - Access the service from the client-side code
- Create an Empty ASP.NET Web Application in your solution.
- Drag and drop an AJAX Extensions ScriptManager control into your web page.
- In the
ServiceReference
Collection Editor, set the path to http://GooberServer:90/FooServiceOne.svc
- Drag and Drop an ASP.NET button and Label control on the page.
<asp:Button ID="Button1" runat="server" OnClientClick="return Button1_Click();" Text="Add 5 and 7" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
- Add client-side script.
<script language="javascript" type="text/javascript">
function onSuccess(result) {
document.getElementById('<%=Label1.ClientID %>').innerHTML = result;
}
function Button1_Click() {
var proxy = new GooberFoo.FooServices.IFooServiceOne();
proxy.Add(parseFloat(5), parseFloat(7), onSuccess, null, null);
return false;
}
</script>
- Compile and test.
Step 4 - Modify the service project to allow server-side code to consume the service
- Change the service project's web.config file to look like this.
="1.0"
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="AspNetAjaxBehavior" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AspNetSOAPBehavior">
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="GooberFoo.FooServices.FooServiceOne" behaviorConfiguration="AspNetAjaxBehavior" >
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<endpoint address="soapreq" behaviorConfiguration="AspNetSOAPBehavior" bindingConfiguration="basicHttpBinding"
binding="basicHttpBinding" contract="GooberFoo.FooServices.IFooServiceOne" name="GooberFoo.FooServices.IFooServiceOne" />
</service>
</services>
</system.serviceModel>
</configuration>
Step 5 - Test the Service.
- In IE, open the URL http://GooberServer:90/FooServiceOne.svc.
- You will see the FooServiceOne Service page along with instructions to use svcutil.exe http://GooberServer:90/FooServiceOne.svc?wsdl
Step 6 - Add the Web Reference to your asp.net web application.
- In your web application, "Add Service Reference".
- Use http://GooberServer:90/FooServiceOne.svc?wsdl
- Click Go.
- Use
FooServiceOneRef
as the namespace.
- Click OK.
- View web application’s web.config file.
- It’s changed quite a bit.
- You will see the
system.serviceModel
node that includes the bindings and client nodes.
- You will not need to change anything.
7. Use server-side C# code to consume the service in your web application.
- Add Button control to the page along with a button click event.
<asp:Button ID="Button2" runat="server" Text="Add 10 and 13" onclick="Button2_Click" />
- The button click event will look like this:
protected void Button2_Click(object sender, EventArgs e)
{
FooServiceOneRef.FooServiceOneClient mySvc = new FooServiceOneRef.FooServiceOneClient();
Label1.Text = Convert.ToString(mySvc.Add(10, 13));
}
- Compile and test.
Points of Interest
By far the most challenging part was the service application' web.config file.