What is REST?
Here are definitions:
“Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use.”
Principles (taken from Wikipedia):
“REST’s proponents argue that the web has enjoyed the scalability and growth that it has as a result of a few key design principles:
Application state and functionality is divided into resources
Every resource is uniquely addressable using a universal syntax for use in hypermedia links
- All resources share a uniform interface for the transfer of state between client and resource, consisting of
A constrained set of well-defined operations
A constrained set of content types, optionally supporting code-on-demand
A protocol that is:
Client/Server
Stateless
Cacheable
Layered”
This is a contrast to a RPC (Remote Procedure Call) model, which is commonly implemented using SOAP or the simpler XML-RPC. There, you expose a range of methods or procedures that can be called and supply them with data to operate on. The focus here is on verbs – the operation that is being performed.
Let’s build a very simple REST-full WCF service. I am going to use Visual Studio 2008 and for testing service Fiddler.
Open Visual Studio and create new WCF service library.

Change the name of the IService1 interface to IHelloRest and class Service1 to HelloRestService.
Add reference System.ServiceModel.Web to this project.
Remove all operations from the IHelloRest interface and add first test operation. Observe here WebGet attribute which allows clients to use your services using HTTP GET attribute. Also observe message format – JSON and UriTemplate.
IHelloRest.cs:
[System.ServiceModel.ServiceContract]
public interface IHelloRest
{
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebGet(UriTemplate = "helloto/{name}", ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json)]
string Hello(string name);
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebGet(UriTemplate = "isalive/{animal}", ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json)]
Animal CheckIfAlive(string animal);
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebInvoke(UriTemplate = "animals", ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Xml)]
Animal[] PostAnimal(Animal animal);
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebGet(UriTemplate = "gallery/{pictureId}")]
System.IO.Stream GetPictureThumbnail(string pictureId);
}
[System.Runtime.Serialization.DataContract]
public class Animal
{
[System.Runtime.Serialization.DataMember]
public bool IsAlive { get; set; }
[System.Runtime.Serialization.DataMember]
public string Name { get; set; }
}
And HelloRestService.cs
public class HelloRestService : IHelloRest
{
#region IHelloRest Members
public string Hello(string name)
{
return String.Format("Hello:{0}", name);
}
public Animal CheckIfAlive(string name)
{
return new Animal { IsAlive = true, Name = name };
}
public Animal[] PostAnimal(Animal animal)
{
List<Animal> a = new List<Animal>();
a.Add(new Animal { IsAlive = false, Name = "mamut" });
a.Add(new Animal { IsAlive = true, Name = "dog" });
a.Add(new Animal { IsAlive = true, Name = "ape" });
return a.ToArray();
}
public System.IO.Stream GetPictureThumbnail(string pictureId)
{
System.IO.Stream stream = System.IO.File.Open(@"ow.jpg",System.IO.FileMode.Open);
// set the Content-Type to image/jpeg
System.ServiceModel.Web.WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
return stream;
}
#endregion
}
Now add new Console Project to the same solution. Add also application configuration file to this project and insert.
Add System.ServiceModel, System.ServiceModel.Web and HelloRest(WCF Library) reference to console project.
Here is my app.config:
<configuration>
<system.serviceModel>
<bindings>
</bindings>
<services>
<service name="HelloRest.HelloRestService" behaviorconfiguration="Default">
<host>
<baseAddresses>
<add baseaddress="http://localhost:8081/json"></add>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="HelloRest.IHelloRest"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpgetenabled="true"></serviceMetadata>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
And here is Program.cs:
class Program
{
static void Main(string[] args)
{
using (WebServiceHost serviceHost = new WebServiceHost(typeof(HelloRest.HelloRestService)))
{
serviceHost.Open();
Console.WriteLine("WCF Service is running...");
Console.ReadLine();
serviceHost.Close();
}
Console.WriteLine("WCF Service has closed");
}
}
Now start console application and your service should be running.
Now we can use fiddler to test our service:
Open fiddler and type in the request builder url with inparameter({name} defined in the interface) to your REST service.
You should get something like this:

Now if you click on result to the left and open Session View you should see this:

Your Rest service worksJ
Now test other operations returning complex types:
If you test http://localhost:8081/json/isalive/dog, you should get animal object in JSON like this:
{”IsAlive”:true,”Name”:”dog”}
Now let’s try to get an image with GetPictureThumbnail
operation. Add an image to the console project and under properties in the project for the image change “Copy to Output Directory” to copy if newer.
You should also change in the code for the operation to the name of your image.
Write http://localhost:8081/json/gallery/1 in the fiddler or the browser and you should get back image. This operation could be used by passing picture id and returning thumbnail when generating gallery.
At the end we will test post with PostAnimal operation. In the Request Builder (Fiddler) write in the Request Header and change Get TO POST:
User-Agent: Fiddler
Host: localhost:8081
Content-Type: application/json; charset=utf-8
Content-Length: 0
See image:
Result should be something like this:
That was simple……



Aman,
I don’t seem to be able to figure it out how to pass objects to a method call, as in your PostAnimal method;
[System.ServiceModel.OperationContract]
[System.ServiceModel.Web.WebInvoke(UriTemplate = "animals", ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Xml)]
Animal[] PostAnimal(Animal animal);
An ‘Animal’ is a parameter of the method but you do not pass it to the method call when testing it in the Fiddler. Why?
Could you show me how to do it.
Thanks,
Roman
By: Roman on July 1, 2008
at 2:05 pm
Hi Roman
. Here is how you could do.
Sorry for late answer, I got back from vacation yesterday
1. In IHelloRest.cs change Animal class like this:
[System.Runtime.Serialization.DataContract(Name = "Animal",Namespace="")]
public class Animal
…
2. In HelloRestService.cs change PostAnimal like this:
public Animal[] PostAnimal(Animal animal)
{
List a = new List();
//a.Add(new Animal { IsAlive = false, Name = “mamut” });
//a.Add(new Animal { IsAlive = true, Name = “dog” });
//a.Add(new Animal { IsAlive = true, Name = “ape” });
a.Add(animal);
return a.ToArray();
}
3. Start Service and start fiddler
4. Navigate to http://localhost:8081/json/animals in request builder with POST
5. Add this to Request header
User-Agent: Fiddler
Host: localhost:8081
Content-Type: application/xml; charset=utf-8
Content-Length: 57
and
this in Request Body
By: dotnetninja on July 7, 2008
at 7:22 pm
This post has been very helpful for me, one question though. Building on your last answer… what if Animal included a custom enumeration? I can’t seem to get that to work with PostAnimal.
Thanks,
James
By: james on October 17, 2008
at 4:59 pm
I figured it out… I had to remove the DataContract attribute from the enum.
-James
By: james on October 17, 2008
at 5:24 pm
Hi
I’m glad that I could help you and great about finding solution with enum
By: dotnetninja on October 17, 2008
at 9:35 pm
Hey,
What happens to the stream handle after it is returned?
There is no explicit location where you can Close the stream.
Using the “using” statement also returns an empty file.
Do you know what’s going on behind the scenes?
By: Itamar on June 7, 2009
at 1:42 pm
Investigating…
Check out WCF Starter Kit with AdapterStream there is an example there using AdapterStream (PushStyleStreaming)
By: dotnetninja on June 8, 2009
at 11:37 am