Modern applications often require the ability of multiple client interfaces (e.g. web browser, iPhone, Android device, etc) to access data stored in a central repository. The standard interfaces used to serve this data to the devices are referred to as Restful web services. In this tutorial, we will build a restful web service to send a question, an answer, a JPEG image, and an mp3 audio file to a device which requests the data from the server using a test number and question number as parameters. (to see how we would build a standard client using javascript and jquery to communicate with our service, click here).

Building the database

We will build the server on a Microsoft Windows box running a SQL Server database. We will build a table with the following fields:
[Testno] [int] NOT NULL
[Questionno] [int] NOT NULL
[Question] [nvarchar](80) NOT NULL
[Answer] [nvarchar](80) NOT NULL
For these tests, we not only want the ability to send the question/answer pair from the server to the client, but also an mp3 audio file and a jpg image file. In order to make use of the SQL-Server feature that allows access from the database to the file system for binary files, we will enable the SQL-Server FILESTREAM capabilities as follows in the instance properties:

Next, enable FILESTREAM for the instance in the SQL-SERVER configuration manager:

We can now build the database which will house our table by using the following SQL:

Next, we want to build the table with the desired fields into the VokabelTests database and insert a row for testing purposes. This can be done by using the following SQL:

We now have a database table called vokabel_tests which contains one record that we can test with.

Building the Web Service to serve question and answer data

We will be using C# in the Visual Studio environment to build the web service. Once we have built the service to return the data, we will build a client program in Javascript to request the data from the server through a web browser.

The first step will be to create a WCF service project in Visual Studio:

Next, edit the IService1.cs interface file and add the GetQuestion Method interface that will allow the client to request question data based on the test number and question number.

Add a stub to the Service1.svc.cs file with the GetQuestion method (it will only echo the values passed to it for now).

Modify the web.config file so that it looks as follows (you will comment out the serviceHostingEnvironment:

Finally, right-click on the Service1.svc file and select "view markup" to add the Factory= entry:

<%@ ServiceHost Language="C#" Debug="true" Service="VokabelService.Service1" CodeBehind="Service1.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

Right-clicking on the service1.svc file and selecting View in Browser should now let you view what your service returns when you pass the testno/questionno pair

We now have a functioning web service that returns the initial parameters sent to it to a client program.

Modifying the web service to return a question/answer pair from the database in json format

We will now be making use of the data in the database to return the question/answer pair that corresponds to the testno and questionno requested by the client program. The first thing we will do is to create a "QuestionClass" that will hold the data associated with the question as well as the various methods (including database access) that could act on it.

To do this, right-click on the VokabelService, click Add->New Item->Class, naming the class QuestionClass.cs

For normal applications, we would put the database connection in its own class, but since a web service will reconnect to the database at each request, we can implement the connection within the QuestionClass. The constructor receives the testno and questionno and populates the instance with the correct question/answer pair.

Since we are now getting the data through the QuestionClass class, we must also modify the Service1.svc.cs file that previously returned a canned response directly.

Running the service and accessing it via browser with parameters testno=1 and questionno=2 returns the following:

Expanding the Web Service functionality to serve jpeg and mp3 data

We will now expand the functionality of the web service by adding 2 new web services.
  1. GetImage - will return the jpeg image that we earlier loaded into the vokabel_tests table when the corresponding testno/questionno is requested
  2. GetAudio - will return the mp3 audio file that we earlier loaded when the corresponding testno/questionno is requested
The first step is to modify the IService1.cs file to add the interfaces to our new services. It will look as follows:

We will next create ImageClass.cs and AudioClass.cs classes by right clicking on our services and selecting Add->New Item->Code->Class.

The ImageClass will contain one FileStream variable called imagestream that will point to the location of the Image file that we will be querying from the database (passing testno and questionno as query parameters in the constructor). The processing of the binary image file is somewhat more complicated than the text question and answer pair that we returned earlier because we have to process a stream of bytes and write it to a file. Once we have created the file, we will close it and reopen it in read-only mode so that the filestream pointer that we are storing is pointing to the beginning of the file.

Audioclass.cs is almost identical except that we will call our FileStream variable audiostream.

In the final step, we will modify the Service1.svc.cs file to return the image and audio filestream to the calling clients. Note that we must specify that we are returning jpeg and mp3 files so that the calling program knows how to interpret the data.