WCF Web Services & iOS - Part 1

By Mike Gledhill

Pages:

In this section, we're going to go through the steps required to make a WCF Web Service in Visual Studio 2012.
As you'll see, it's quite straight forward if you get all the steps right.

Personally, I found it hard to find one up-to-date resource which would take me through these steps.

Our ultimate goal is to send data from a SQL Server database to an iOS device.
We will create a WCF Web Service to read in data from the SQL Server database, and return it in a generic, non-Microsoft (JSON) format, which the iOS device will be able to understand.

SQL Server, to iOS, via WCF Web Services

This section deals with setting up and testing a very basic WCF Web Service, which returns JSON data, and is ready for us to link to the Northwind SQL Server database in the next section.

To follow this tutorial, you will need the following:

  • A copy of Microsoft Visual Studio 2012 or 2013

Creating the WCF Web Service

1. Start Visual Studio 2012
2. Create a new project
Click on File \ New \ Project.
Make sure WCF is selected in the left part of the window, then select the project type WCF Service Application.
In the Name textbox, type in JSONWebService.
We're going to create a .Net Framework 3.5 web service, so make sure this is selected at the top of the dialog.
Then click on OK.
3. Run the project
Click on Debug \ Start Debugging to run this sample project.
At this point one of two things will happen. Either a browser window will appear listing the files in your web service project (shown below on the left), or the WCF Test Client will open, connect to your service, and show a list the two web services which Visual Studio 2012 has added to your project.
Browser list of files, or WCF Test Client
Ideally, we'll want the WCF Test Client to start each time we run this project. This only happens if you have the IService.svc file defined as the Start Page, so, our first step is to make a couple of changes to the Project settings to make sure this happens each time.
Stop debugging now, and in Solution Explorer, right click on the project name, then click on Properties.
Project properties
On this screen, click on the "Web" tab, then make the following two changes:
- For "Start Action", click on the "Specific Page" radio button, then use the "..." button to choose the "Service1.svc" file.
- For "Use Visual Studio Developer Server", click on the "Specific Port" radio button, and type in 15021.
This second step isn't actually a requirement, but just means that your app will use the same Port numbers as the examples shown below, and you'll be able to run exactly the same URLs that I show you.
Close the Properties screen, re-run the project, and make sure that the "WCF Test Client" does start this time.
4. Run one of the sample web services
Visual Studio has provided us with two sample web services. Let's test the GetData web service using the WCF Test Client. Simply, double click on the GetData() service, enter a number in the Value column, then hit the "Invoke" button, you can see the response which the web service returns for us.
The WCF Test Client
5. Change the web service to return JSON results
Next, we're going to change this GetData web service, so we can call it directly from a web browser.
Once we've done this, we'll be able to call the web service, and see it's results, simply by passing in the web service name (e.g. GetData) and our numeric value (e.g. 13) within the URL:
Our modified web service
To do this, we need to make some changes to the sample code. First, we need to change GetData's parameter type from "int" to "string"
Open up the Service1.svc.cs file, and change the "value" parameter to be a string:

public string GetData(string value)
{
    return string.Format("You entered: {0}", value);
}

Now, hop across to the IService1.cs file, and replace the original lines

[OperationContract]
string GetData(int value);

...with this..

[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "getData/{value}")]
string GetData(string value);


Let's just take a quick look at the new WebInvoke line we've just added.
The ResponseFormat attribute tells WCF that we want our service to return a JSON string. If you were to miss out this ResponseFormat setting, the web service would still work, but it would return your value in XML format instead:

<GetDataResponse xmlns="http://tempuri.org/">
    <GetDataResult>You entered: 13</GetDataResult>
</GetDataResponse>

Note also that we set the UriTemplate attribute, to specify that we will always be passing a parameter when we call this URL. So, we've set the UriTemplate as this..

UriTemplate = "getData/{value}"

..as we are going to call this function and always pass it a parameter, like this..

http://localhost:15021/Service1.svc/GetData/13


Now, open up the web.config file, and add the following <endpointBehaviors> tag, just after the <serviceBehaviors> tag.

<behaviors>
  <serviceBehaviors>
    <behavior name="JSONWebService.Service1Behavior">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="webBehaviour">
      <webHttp/>
    </behavior>
  </endpointBehaviors>

</behaviors>

Next, further up in the web.config file, search for the <services> tag, and replace the <endpoint> lines with the following lines. (Don't be surprised if this means replacing several lines of configuration with this one <endpoint> tag.)

<system.serviceModel>
  <services>
    <service name="JSONWebService.Service1" behaviorConfiguration="JSONWebService.Service1Behavior">
      <endpoint address="../Service1.svc"
          binding="webHttpBinding"
          contract="JSONWebService.IService1"
          behaviorConfiguration="webBehaviour" />

    </service>
  </services>
  ...etc...

And that's it.
Let's run the project again.
This time, ignore the WCF Test Client, and instead, open up a browser, and try running the web service with your own parameters, for example:

http://localhost:15021/Service1.svc/GetData/13

http://localhost:15021/Service1.svc/GetData/SomeNumberorOther

If you're running the Chrome browser, you'll see the results straightaway:
Our modified web service
However, if you're running Internet Explorer, you'll probably see this instead:
Do you want to save this file?
Ridiculously, Internet Explorer doesn't display JSON data by default, and insists on saving it to an external file.
Thankfully, there's a simple solution to this.
Download and run this reg file to change the two registry settings on your PC, which will allow IE to automatically display JSON results. Then, close and re-run Internet Explorer, and try the URL again.
Internet Explorer, tamed.
(This excellent fix was take from this Stack Overflow page.)
So, the good news is that we can now call our web services directly from a browser, and instantly see the results. The bad news is that we can no longer use the WCF Test Client, as it doesn't work with JSON/REST services like these.

Summary

Brilliant !
We haven't actually started writing our Northwind web services yet, but at least the pieces are in place for us to begin. (And what you don't realise is that it took me hours of experimenting and Googling to get this far myself !)
By the way, did you notice that the web service returned:

{"GetDataResult":"You entered: 13"}

..rather than just..

You entered: 13

This is because we modified our GetData web service to return JSON data, so the WCF Web Service has automatically converted our output into JSON format.
This isn't much help in this simple example, but will be very useful in the next section, when we start returning database records in our results.
 

Disclaimer

You'll notice I'm deliberately not explaining what all of these changes are for, or what they mean. There is a wealth of bulky articles out there to explain all of this (for example, try Googling "web.config endpoints" if you want to understand why we added this change to the web.config file) but my aim is to simply show you how to create a complete, general purpose, reuseable web service project with as little pain as possible.
This is the article I wish that I'd had, when I faced all of these challenges.
< Previous Page
Next Page >

Comments

blog comments powered by Disqus