I had to develop a WCF Service that is serving SOAP and JSON (also JSONP) Messages.
The clients were WCF Clients and jQuery.ajax() web-Clients.
There are many samples on the web, but None was working for me. So here is a working one 🙂

Table of Contents

  1. WebService Interface
  2. WebService Implementation
  3. Adjust web.config
  4. Create jQuery.ajax() Client
  5. Download

WebService Interface

As in every example you should create an webservice Interface. I was missing line 5 and 9 to allow a GET operation on those two methods. Further the lines indicate, that JSON should be returned.

[ServiceContract]
public interface IWeatherService
{
    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    Weather GetCurrentWeather(int zipLocation);

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    Weather[] GetForecast(int zipLocation);
}

[DataContract]
public class Weather
{
    [DataMember]
    [DataType(DataType.Date)]
    public DateTime Date { get; set; }

    [DataMember]
    public string WeatherAsString { get; set; }

    [DataMember]
    public int Zip { get; set; }
}

WebService Implementation

Here is my implementation of the webservice. Nothing special here.

public class WeatherService : IWeatherService
{
    public Weather GetCurrentWeather(int zipLocation)
    {
        return GetDummyData().Single(q => q.Date.Date == DateTime.Now.Date && q.Zip == zipLocation);
    }

    public Weather[] GetForecast(int zipLocation)
    {
        return GetDummyData().Where(q => q.Zip == zipLocation).ToArray();
    }

    private IEnumerable<Weather> GetDummyData()
    {
        var data = new List<Weather>();

        // Weather on ZIP Location 12345
        data.Add(new Weather { Date = DateTime.Now, WeatherAsString = "Sunny", Zip = 12345 });
        data.Add(new Weather { Date = DateTime.Now.AddDays(1), WeatherAsString = "Partly Cloudy", Zip = 12345 });
        data.Add(new Weather { Date = DateTime.Now.AddDays(2), WeatherAsString = "Rainy", Zip = 12345 });

        // Weather on ZIP Location 54321
        data.Add(new Weather { Date = DateTime.Now, WeatherAsString = "Rainy", Zip = 54321 });
        data.Add(new Weather { Date = DateTime.Now.AddDays(1), WeatherAsString = "Rainy", Zip = 54321 });
        data.Add(new Weather { Date = DateTime.Now.AddDays(2), WeatherAsString = "Rainy", Zip = 54321 });

        return data;
    }
}

Adjust web.config

I was really struggling with the web.config configuration. I want to point out that my service uses the same methods for SOAP and JSON. For this you need to specify two different endpoints! (as shown in line 14 and 15).
One is listening on http://URL/WeatherService.svc/soap/METHODNAME and the other one on http://URL/WeatherService.svc/json/METHODNAME.

On line 37 i’m going to allow cross domain calls. (The JSONP Thing). If you leave this out you will not be able to make cross domain calls. Depending on your needs.

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  
  <!-- WCF Configuration goes here -->
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="false" />

    <services>
      <service name="de.sirz.DemoWebService.WeatherService" behaviorConfiguration="WebServiceBehavior">
        <endpoint address="soap" binding="basicHttpBinding" contract="de.sirz.DemoWebService.IWeatherService"/>
        <endpoint address="json" binding="webHttpBinding"  behaviorConfiguration="jsonBehavior" contract="de.sirz.DemoWebService.IWeatherService" bindingConfiguration="webHttpBindingWithJsonP" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior name="jsonBehavior">
          <webHttp helpEnabled="true" />
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="WebServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>

  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

Create jQuery.ajax() Client

Finally i implemented a jQuery.ajax() call. You could also do this with jQuery.getJSON() but to be more flexible when using different verbs like GET, POST, PUT etc i decided to use jQuery.ajax() on every call.

Notice: The method i call is: http://localhost:54772/WeatherService.svc/json/GetCurrentWeather. I missed the ‘json’ for a while 😉

$.ajax({
	type: "GET",
	data: { "zipLocation": "12345"},
	dataType: "jsonp",
	url: "http://localhost:54772/WeatherService.svc/json/GetCurrentWeather",
	success: function (data) {
		alert('success. handle data.')
	},
	error: function (error) {
		alert("implement error handling. tbd. " + error);
		console.log(error);
	},
});

Download

You can download the sources here.


Picture taken from here