Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Simple Demo WCF RESTful Web Service

5.00/5 (13 votes)
20 Apr 2015CPOL28 min read 62.8K   2K  
A quick look at a Simple WCF RESTful Web Service!

Table of Contents

  1. Introduction
  2. WCF RESTful Service- Introduction
  3. Look at our project TweetBL defining simple Business Functionality
  4. Creating a WCF RESTful Service project (for TweetBL Project's Business Functionality)
  5. Running the default WCF RESTful Service project (Project still has AJAX configuration for Web.config)
  6. Modifying and running default Tweet.WCFService.RESTful Project settings (switching from AJAX to RESTful)
  7. Running Tweet.WCFService.RESTful Project - the simple way!
  8. Building WCF RESTful Service project (for TweetBL Project's Business Functionality)
  9. Running the WCF RESTful Service project (now with our Business Code)
  10. Creating and Testing WCF RESTFul Web Service Client
  11. Final Thoughts

Introduction

In this article, we will be looking into creating a WCF RESTful Web Service!

I would recommend giving a quick read to this article to get a brush up on basic WCF details.

I will focus on covering WCF RESTful Service related topics in this article and will not divulge the basic WCF related details example - explaining Operation Contracts. The above linked article explains these topics.

Also here is the link for the article on WCF AJAX Web Service, written by me. AJAX Web Servcie and RESTful Web Service bear a lot of resemblance as you will see during the course of this article. I have provided the link for you to look at because both leverage Web API. I would recommend to give it a quick read before going ahead with this article, as I firmly believe it will ease things for you to understand.

That being said, if you follow this article, it should not be hard for you to grasp the concept. So, don't worry as you can read them later.

We will be using a simple business layer project called TweetBL in this article to start things up. During the course of this article, we will expose the business functionality of TweetBL as a WCF RESTful Web Service.

We will be focusing on churning out a WCF RESTful Web service in this article and I have tried my best to keep it as simple as one can.

Following the KISS concept: "Keep it Simple Stupid."

So let's get the ball rolling...

WCF RESTful Service - Introduction

I still maintain... Windows Communication Framework (WCF) is as interesting as the Marvel Universe! no kidding.

WCF is a framework which supports message-based communication between client and server.

WCF is highly configurable...!!

We will leverage this trait of WCF by employing WebHttp behaviour configuration option! WebHttp behaviour provides for XML and/or JSON serialization instead of using the traditional SOAP envelopes! WebHttp also binds custom routes for each individual operation exposed via our service.

Needless to add, it also allows for multiple HTTP verbs mentioned below:

  1. GET verb: used for fetching data
  2. PUT verb: used to update data
  3. POST verb: used to insert data
  4. DELETE verb: used to (you guessed it right!) delete data

In short, WebHttp behaviour provides for the required functionality for WCF to develop a REST based web service.

Note, we will also be using WebHTTPBinding service binding as this allows us to make the connections from a web service to service methods using the predefined behaviours.

Furthermore, WCF RESTful web service is still a style of Web API style of Web Service. This means that no WSDL (Web Service Definition Language) file will be generated for a RESTful web service.

So, we have been talking about RESTful a lot... what it actually is? Well, REpresentational State Transfer (REST) is a style of Web API web service that follows a few structural guidelines (such as Uniform Interface) when it comes to accessing, updating and retrieving data!

A few highlights of REpresentational State Transfer (REST) are:

  1. Uniform Interface RESTful uses specific HTTP verbs for specific actions:
    • GET: translates to Read action
    • PUT: translates to Update action
    • POST: translates to Insert/Create action
    • DELETE: translates to well Delete action
  2. RESTful Web services also prefer a specific style of URI (demonstrated in point 3 with yourService.com example) that they use to access and manage information (data/resource). RESTful prefers representing the data that they manage as resources.
  3. Promotes cleaner URIs Example: yourService.com/SocialNetworker/1251/Tweets instead of using a query string URI... yourService.com/GetAllTweetsForSocialNetworker?SocialNetworkerId=1251

So enough of talking...

Time to roll-up our sleeves and get started!

Look at our Project TweetBL Defining Simple Business Functionality

We will expose TweetBL projects Business Functionality as a Web Service!

The project that we will be exposing as a Web Service is a simple class library project called TweetBL.

Project TweetBL represents the business code that has been identified to be made available over the web as a WCF RESTful web service.

TweetBL project has the following business functionality (methods) that will be exposed as a service.

Business functionality methods are:

  1. Update tweet
  2. Save/insert a tweet
  3. Delete a tweet
  4. Retrieve tweet by id and
  5. Retrieve all tweets

TweetBL Project:

TweetBL Project Screen-shot

Tweet.cs is simply the data class identifying all data members that we have to fetch/update/insert and delete to manage tweets. Think of Model (Data Model).

Tweet.cs Class Screen-shot

ManageTweet.cs is the class that houses the business methods that do all the necessary processing on the Tweet data to manage and maintain it.
Note: There is a bit of housekeeping code as well because we are not using an actual database to keep things fairly simple.

ManageTweet.cs Class Screen-shot

TweetBL project tour is over... that is it with TweetBL functionality... it is indeed fairly simple!

Let's start with writing a RESTful web Service for our TweetBL project.

We shall dedicate this RESTful service to all the dedicated "Twitterati's" out there... once it is completed :P

Creating a WCF RESTful Service project (for TweetBL Project's Business Functionality)

Now that we have had a quick trip of our TweetBL Project, it is time to jump into some real code...

Let's us start by adding a new project called Tweet.WCFService.RESTful. This will be our WCF RESTful Service project.

Adding Tweet.WCFService.RESTful Project Screen-shot

Select the Empty option and nothing else.

Adding Tweet.WCFService.RESTful Empty Project Screen-shot

Tweet.WCFService.RESTful Project added Screen-shot

The above step has created an empty ASP.NET Web Application for us!

Now, we will add a WCF RESTful Service to Tweet.WCFService.RESTful project.

Go to add new item (on Tweet.WCFService.RESTful project) and follow the screen-shot below:

Tweet.WCFService.RESTful Adding New Item Screen-shot

Tweet.WCFService.RESTful Added New RESTful Service Screen-shot

As soon as we add the AJAX service, a few changes were made to our project.

A few references and libraries from .NET were added to our project. We will cover a few interesting bits!

Our Web.config file has also been modified!

Our Web.config file has been modified (by default) for developing an AJAX Service but we will modify it to develop a RESTful service soon. Let us have a look at that...

Tweet.WCFService.RESTful Web.Config AJAX Configuration Screen-shot

Note*: <enableWebScript /> behaviour is used to develop a WCF AJAX Web Service. But as we are developing a RESTful web service, we will make the necessary modifications to Web.config.

Also, an <endpointBehavior> has been added to our Tweet.WCFService.RESTful project which will enable listening of request calls for web services.

Notice the binding used "webHttpBinding". This allows our web service clients to communicate with our service using http GET and POST verbs. Note only the methods decorated with Operation Contract attribute are exposed as services.

Along with the above changes, we are also provided with a template file for our TweetService.svc class.

Tweet.WCFService.RESTful TweetService.svc templete file Screen-shot

Here unlike: SOAP over HTTP Web Services, we do not have an interface class.

The Service Contract and Operation Contract attributes are directly defined on the class. Also, take a note of AspNetCompatibilityRequirements attribute: this attribute indicates that this service integrates with the ASP.NET pipeline. Now that we have created a project and have had a quick tour of what we have been given by default to work with... let's take a step further towards building the real thing!

Running the Default WCF RESTful Service Project (Project still has AJAX Configuration for Web.config)

So in our WCF project Tweet.WCFService.RESTful let's start things by running the default code that we got after creating the project. This can be done by right clicking on TweetService.svc and selecting view in browser!

Tweet.WCFService.RESTful TweetService.svc view in browser Screen-shot

Tweet.WCFService.RESTful TweetService.svc default service-run in browser Screen-shot

Beauty! The auto generated HTML page. Now this is a Web API service so no WSDL is generated!

Of course, we have come this far and there is no harm in testing the default DoWork method that we saw in class TweetService.svc.

To do this, all we have to do is add a new attribute to the DoWork Method. The new attribute is WebGet is shown below in the screen-shot.

Tweet.WCFService.RESTful TweetService.svc WebGet attribute Screen-shot

Naturally, you would want to know what WebGet attribute does? Basically, WebGet attribute exposes operations (decorated with it) using the GET verb! Now our DoWork service is directly accessible via a Web browser by typing the URI to the service (TweetService.svc in our case) followed by the method/operation name (DoWork in our case) into the address bar.

This is what we will do next.

After adding this new attribute, again, we go right click on TweetService.svc and select view in browser.

Type in method DoWork at the end of the path... and hit enter.

Tweet.WCFService.RESTful TweetService.svc DoWork URI Call Screen-shot

the fruits of our labour...

Tweet.WCFService.RESTful TweetService.svc DoWork URI Call result Screen-shot

{"d":null} is the response that we got back by making a call to DoWork service operation. This is in JSON format.

Calling AJAX Services is this simple!

All that we have done above is run WCF AJAX web service because remember we have not yet modified Web.config file to indicate that this is a RESTful web service.

Let us do that next!

Modifying and Running Default Tweet.WCFService.RESTful Project Settings (Switching from AJAX to RESTful)

To begin with... one of the first things that we would need to do now is define a URI for our WebGet attribute because REST places a very high importance on clean resource URIs.

This means that REST expects us to specify a specific URI to access a specific method or a specific resource.

To accomplish this, we have to pass parameters to WebGet attribute.

To be precise, we will be employing the UriTemplate parameter.

Modify DoWork Method in TweetService.svc as below:

C#
// class code...
[OperationContract]
[WebGet(UriTemplate="/DoWork")]
public void DoWork()
{
    // Add your operation implementation here
    return;
}
// class code...

TweetService.svc Class now..

Tweet.WCFService.RESTful TweetService.svc DoWork URI RESTful Call result Screen-shot

UriTemplate parameter basically allows us to pass a string which allows us to define a template for the URI that the hosting provider (in our case Web Dev server) matches with the incoming requests!

Now we are ready to invoke the DoWork Service method..... RESTful web service style!

Oooohh... something unexpected has happened!

Tweet.WCFService.RESTful TweetService.svc DoWork URI RESTful Call FAIL result Screen-shot

This is a Server error: indicating that we have used "UriTemplate" to bind a URI to a specific method but we are not allowed to do that with our current configuration! (We are still on AJAX Web Service Configuration).

Making necessary changes to Web.conf file in Tweet.WCFService.RESTful project time to move to RESTful configuration.

Web.config current state...

Tweet.WCFService.RESTful Web.config default with enablewebscript Screen-shot

We specifically want to switch from <enableWebScript /> to <webHttp /> <webHttp> is a WCF behaviour which provides us with more relaxed and flexible control over the HTTP communication than what <enableWebScript> provides us with.

Why? are we doing this switch?? Still puzzled... Well.. even <enableWebScript> uses HTTP verbs to communicate and serialize and de-serialize data (using XML or JSON) but it does so with the help of a default automatically generated JavaScript Proxy! which has its own ways of doing things.

Whereas in RESTful we would not like to use this default JavaScipt proxy as we would like more control on HTTP verbs! we want to determine ourselves which HTTP verb should be bound to which method.. along with the URIs! that we would want to define and use. <webHttp> allows to define these all in our WebGet and WebInvoke attributes.

More about this automatic generated JavaScript Proxy can be read here in WCF AJAX Web Service article (i.e., if you are curious... you can read it later.. as well.)

Making the change... in Web.config file (Tweet.WCFService.RESTful project)

Tweet.WCFService.RESTful Web.config with webHttp Screen-shot

Time to run TweetService.svc DoWork method again...

Tweet.WCFService.RESTful TweetService.svc with webHttp Screen-shot

Tweet.WCFService.RESTful TweetService.svc DoWork return NULL with webHttp Screen-shot

...and DoWork executes with no problems. Needless to add, the DoWork method has a void return type and hence the executing DoWork method gives us nothing back to display.

The UriTemplate parameter helps the server (in our case Web Dev) determine how the incoming request should be processed! It helps to deduce which service method should respond to which specific incoming request.

Let us change the UriTemplate parameter for DoWork method from /DoWork to /GetSomethingDone...

This will demonstrate the importance of UriTemplate parameter! because when we will try to invoke DoWork method using /DoWork URI, it will report Endpoint not found! as we have now changed the URI to get to DoWork method to /GetSomethingDone.

Changing the UriTemplate Parameter in TweetService.svc.

Tweet.WCFService.RESTful TweetService.svc DoWork with /GetSomethingDone UriTemplate Screen-shot

Invoking DoWork method with old UriTemplate URI of /DoWork...

Tweet.WCFService.RESTful TweetService.svc DoWork with /GetSomethingDone UriTemplate invoking /DoWork Screen-shot

Server cannot determine how to handle this as we have mapped UriTemplate to /GetSomethingDone.

Now let's invoke the DoWork method using the Correct URI.

Tweet.WCFService.RESTful TweetService.svc DoWork with /GetSomethingDone UriTemplate invoking /GetSomethingDone Screen-shot

and behold the void of DoWork method is back!!

With the role and importance of UriTemplate now well understood... let us take a step forward towards exposing the real TweetBL Business methods rather than DoWork (default method) as part of our much anticipated TweetService!

But before going any further, let's take a small detour to make running TweetService.svc much simpler - just by using F5!

This will definitely make our life much easier and is discussed in the next section.

Running Tweet.WCFService.RESTful Project - The Simple Way!

Instead on right clicking: TweetService.svc - and selecting open in browser, we can do the following...

Set Tweet.WCFService.RESTful Project as the Start-Up Project.

Tweet.WCFService.RESTful TweetService.svc Set as Start up Project Screen-shot

Select TweetService.svc and Press F5.

Tweet.WCFService.RESTful TweetService.svc Set as Start up Project Screen-shot

You will get the following error:

Tweet.WCFService.RESTful TweetService.svc WCF Test Client FAILED Project Screen-shot

Well an attempt has been made to launch the WCF Test Client but as no WSDL is generated for RESTful Services, there is no auto generated XML (WSDL) available for the WCF Test Client to tap into and help us with our services Testing... Let us fix this now; so that when we try to run Tweet.WCFService.RESTful after selecting TweetService.svc - WCF Test Client is not employed any more to help us with our services testing!

Let's edit the Project file for Tweet.WCFService.RESTful.

Before we can begin editing, we would need to Unload Tweet.WCFService.RESTful project.

Tweet.WCFService.RESTful editing Project File UNLOAD Project Screen-shot

Once the project is unloaded, right click on the project and select "Edit Tweet.WCFService.RESTful.csproj".

Tweet.WCFService.RESTful editing Project File Edit csproj Screen-shot

Do a "Ctrl+F" for "<WebProjectProperties>".

Tweet.WCFService.RESTful editing Project File WebProjectProperties Screen-shot

Add the following element to the WebProjectProperties for Tweet.WCFService.RESTful project! ans SAVE the File.

XML
<WebProjectProperties>
  // Other Project Properties...
  
  <EnableWcfTestClientForSVCDefaultValue>
    false
  </EnableWcfTestClientForSVCDefaultValue>
  
  // Other Project Properties...
</WebProjectProperties>

Tweet.WCFService.RESTful editing Project File WebProjectProperties EnableWcfTestClientForSVCDefaultValue set to false Screen-shot

After saving the changes to Tweet.WCFService.RESTful.csproj, it is time for us to reload the project...

Tweet.WCFService.RESTful editing Project File Reload Project Screen-shot

Click on YES!

Tweet.WCFService.RESTful editing Project File Reload Project Click YES Screen-shot

Time to set Tweet.WCFService.RESTful project as the Start-Up Project again...

Tweet.WCFService.RESTful editing Project File Setting as Start-Up Screen-shot

Select the TweetService.svc file:

Tweet.WCFService.RESTful editing Project File Select TweetService.svc Screen-shot

In the code behind file for TweetService.svc - Press F5!

And the WCF Test Client did not pop-up! Our TweetService.svc was executed... Tweet.WCFService.RESTful edited Project File in TweetService.svc Press F5 Screen-shot

Now, let's move on and expose our valid TweetBL Business Functionality as part of our RESTful Tweet Service (TweetService.svc). This is done in the next section.

Building WCF RESTful Service Project (for TweetBL Project's Business Functionality)

Time to build our real RESTful Service and remove DoWork method! Let us tap into TweetBL Project - ManageTweet.cs: this class has all the business code that we would need to manage a Tweet. We will expose all these methods as a RESTful Web Service.

Tweet.WCFService.RESTful TweetService.svc with TweetBL Business Methods Screen-shot

In TweetService.svc of Tweet.WCFService.RESTful project, we have included a reference to ManageTweet.cs of TweetBL Project and as demonstrated in the screen-shot above, all we do is pass the call that we receive for any TweetService.svc method to ManageTweet class methods to do the actual work.

Simply put, all we do in our service class is call the business class to do the actual job.

Running the WCF RESTful Service Project (Now with our Business Code)

So now we are ready - to actually run our Tweet Service!

It is not going to be much different... but yes, there are a few extra steps that we will need to follow to run some of the methods! which do not implement the GET verb (WebGet attribute) but implement WebInvoke attribute. Also, do not worry about the method GetTweetById which expects an ID to be passed in the Uri... it will be very simple to test! The ones pointed out (in TweetService.svc) below:

Tweet.WCFService.RESTful Project TweetService.svc WebInvoke Methods Screen-shot

Trust me, it is good fun...

Testing GetTweets() Method: Follow the steps highlighted in the screen-shots below:

Run the service - Select TweetService.svc and Press F5...

Tweet.WCFService.RESTful Project TweetService.svc Running Service FAILS Screen-shot

and we get the following error!

Tweet.WCFService.RESTful Project TweetService.svc Running Service FAILED MESSAGE Screen-shot

Complete Error Message is: "Operation 'GetTweetByID' in contract 'TweetService' has a path variable named 'tweetId' which does not have type 'string'. Variables for UriTemplate path segments must have type 'string'."

Nothing DRAMATIC here! The complaint is about GetTweetByID method that expects an int tweetId parameter. WCF Rest cannot parse any other value other than strings in the UriTemplate! path.

The offending method(s) well the DeleteTweet method will also offend WCF once we sort GetTweetById!

It is better to sort them out right now!

The method(s):

Tweet.WCFService.RESTful Project TweetService.svc GetTweetById Method Screen-shot

Tweet.WCFService.RESTful Project TweetService.svc DeleteTweet Method Screen-shot

All we have to do is change int tweetId parameter of GetTweetByID method and int deleteTweetId parameter of DeleteTweet method to strings and make the necessary data conversions in our GetTweetByID method and DeleteTweet method for tweetId and deleteTweetId parameters... converting them to int from string before passing them onto corresponding TweetBL methods.

Making the proposed changes -

GetTweetByID method:

Tweet.WCFService.RESTful Project TweetService.svc GetTweetById Modified Method Screen-shot

DeleteTweet method:

Tweet.WCFService.RESTful Project TweetService.svc DeleteTweet Modified Method Screen-shot

Finally, we are back on track...

Now let's give testing TweetService.svc methods a second go!

Testing GetTweets() Method: (Note* GetTweetByID and DeleteTweet methods have been fixed!) Follow the steps highlighted in the screen-shots below:

Run the service - Select TweetService.svc and Press F5...

Tweet.WCFService.RESTful Project TweetService.svc Running Service Will Pass Screen-shot

Type the method name GetTweets:

Tweet.WCFService.RESTful Project TweetService.svc GetTweets Method Call Screen-shot

GetTweets method result (unformatted):

Tweet.WCFService.RESTful Project TweetService.svc GetTweets Method unformatted result Screen-shot

Notice k__BackingField appended to each of our Tweet property... this is because we have not marked our Tweet Class (TweetBL Project) with DataContract attribute and its fields with the DataMember attribute.

TweetBL Project Tweet.cs DataMember Attribute Missing Screen-shot

Quick refresher: Data Contracts defines the type and the format of data that will be sent out and received by the web service operations. Data Member attribute is applied to the fields of the DataContract class that are to be serialized.

I have described a fair bit about WCF contracts in one of my previous articles, the relevant section can be found here.

Applying the attributes to Tweet.cs:

TweetBL Project Tweet.cs DataMember Attribute Added Serialization Namespace missing Screen-shot

Ouch! The red squiggly lines.. ahh.. This just indicates that you do not have reference to the "Serialization" assembly in your TweetBL Project!

C#
namespace TweetBL
{
    using System;
    using System.Runtime.Serialization;
	.... remaining code...	

Let us quickly add reference to "Serialization" assembly:

TweetBL Project Tweet.cs Serilaization reference-1 Screen-shot

TweetBL Project Tweet.cs Serilaization reference-2 Screen-shot

and the world is a happy place again...

TweetBL Project Tweet.cs Serilaization reference-3 Screen-shot

Running TweetService.svc again... we get the following result: k__BackingField is no longer appended.

Tweet.WCFService.RESTful Project TweetService.svc GetTweets Method formatted result Screen-shot

Let's run GetTweetByID() method. This method is decorated with WebGet attribute, but it also expects a Parameter! of type string! to be passed in as well... sweet...

Tweet.WCFService.RESTful Project TweetService.svc GetTweetById Method Screen-shot

Running the TweetService.svc and invoking GetTweetByID method without passing the required string parameter will yield the following result of Endpoint not found:

Tweet.WCFService.RESTful Project TweetService.svc GetTweetByID Method No Param 1 Screen-shot

We got the above result because WCF tried its best to match the requested URI and it failed to locate a matching method. As for GetTweetByID method, the URI states a required string! [WebGet(UriTemplate = "/Tweet/{tweetId}")].

Running the TweetService.svc and invoking GetTweetByID method with just passing the /Tweet will yield the following result of Method not allowed:

Tweet.WCFService.RESTful Project TweetService.svc GetTweetByID Method No Param 2 Screen-shot

Needless to add, none of the other methods defined in TweetService.svc have the URI of /Tweet and are decorated with WebGet attribute!

Method UpdateTweet does have a matching URI but it is decorated with WebInvoke attribute and as we will learn shortly, the way the WebInvoke methods are invoked is a bit different.

By default, our browser only sends WebGet Requests!... so it fails to execute method with URI /Tweet (in this case UpdateTweet method) because it sends the /Tweet with the HTTP request of GET verb and UpdateTweet method is expecting an HTTP request of PUT verb!

Let us pass the required string Id parameter in the URI and see the service work:

Passing 0 to GetTweetByID method:

Tweet.WCFService.RESTful Project TweetService.svc GetTweetByID Method Param = 0 Screen-shot

Stating the obvious here, we do not have a record with id = 0 so, null is returned.

All we need to do is pass in a correct tweet Id (check below):

Tweet.WCFService.RESTful Project TweetService.svc GetTweetById Method with Correct Param Screen-shot

So, this was a simple demonstration on how to run a service operation/method that is decorated with WebGet attribute! and is expecting a string parameter.

It's time to look at the other operations that are decorated with WebInvoke attributes TweetService.svc class...

Tweet.WCFService.RESTful Project TweetService.svc WebInvoke Methods Screen-shot

The key difference between WebGet and WebInvoke attribute is that it uses a POST verb instead of a GET verb that WebGet uses.

Why use WebInvoke? Well the WebInvoke attribute exposes service operations/methods using other HTTP verbs such as POST, PUT, and DELETE. These operations are meant to MODIFY a resource; therefore, the WebInvoke attribute is used to make modifications to a resource. Note: The default option is POST but you can change it by setting the Method Property of the WebInvoke attribute. Demonstrated below:

C#
[OperationContract]
[WebInvoke(Method = "PUT")]
public void PutQuestion(int id, Question question)
{
    // Put question in database
}

Another interesting thing to keep in mind is that all web browsers are optimized to cater to GET verb requests. They cache the result of Get requests and any-time the browser is refreshed, the results are drawn back from browser cache instead of making a trip to the Web Server.

So, for obvious reasons, now when you are performing create, update or delete operations, you do not want browsers to cache the results of these operations! So, we use a different verb like Put, Post and others to indicate that we do not wish to cache the result of these operations and will always like to do a refresh on data once the Put, Post or Delete operation has been completed successfully. It is a Win Win!

Now, moving on... if we try to run the WebInvoke decorated operations, the way we invoked operations decorated with WebGet attribute, we get the following result:

Method CreateTweet - URI: /Tweets

Tweet.WCFService.RESTful Project TweetService.svc WebInvoke Method CreateTweet Screen-shot

Invocation Result:

Tweet.WCFService.RESTful Project TweetService.svc WebInvoke Method CreateTweet run Screen-shot

We get Method not allowed message because we specified WebInvoke attribute for CreateTweet operation.

The question we are asking now is... How do we test our WebInvoke method CreateTweet? The simple answer is we use "Fiddler".

Fiddler: is a utility that allows us to create and monitor HTTP Get/Put/Post/Delete requests! on our machine... just what we need!

There are answers to questions that are to be found... well this question is not one of them :) thanks to Fiddler.

Fiddler Search Screen-shot

Without further ado, download and install Fiddler... (I am on Windows 8) hence I have select Fiddler 4! Please choose 2 or 4 according to the recommendations provided on the website.

Fiddler Selected Screen-shot

Running FIDDLER is simple. Locate Fiddler and run it...

Fiddler Running Screen-shot

Now, let's run method CreateTweet - URI: /Tweets again using Fiddler this time!

So, we want to send a POST request to our TweetService!

Follow the screen-shot below: Paste in TweetService's address and change the type to POST!

Fiddler Connecting to our Service Screen-shot

Add call to CreateTweet's required URI: UriTemplate for the method is /Tweets.

Fiddler Connecting to our Service specifying the correct CreateTweet URI Screen-shot

Now, we need to specify a valid Request Header:

This is because we would like to be upfront about the FORMAT of the data that we will be sending to the Server for processing!

Remember the CreateTweet method expects a parameter of Type TWEET!

CreateTweet Parameter

Specifying the request Header: Content-Type: application/json, our data will be sent in json format to server!

Request Header

Now, we have come to the most important bit! specifying the message body - the data that is to be SAVED in this case! (needless to add, the format is json! as we have specified in our Request Header!)

So, we will be sending a json object to the server to SAVE as part of our call to CreateTweet method!

C#
{
  "Id": 0,
  "PostedBy": "Rahul Pawar via Fiddler",
  "Text": "Saved tweet via Fiddler 4"
}

Request Body for CreateTweet

Time to click on Execute.

Request Body for CreateTweet Execute

Request Body for CreateTweet Execute RESULT

Request Body for CreateTweet Execute Response Headers

The response of 200 indicates everything went well!

A quick call to GetTweets method returns the newly inserted Tweet!

GetTweets after CreateTweet Execute

Time to test our UpdateTweet method: UpdateTweet is decorated with Web Invoke attribute that accepts a HTTP PUT verb request.

UpdateTweet Method

Fire-up Fiddler...

Go to Composer... Enter the address of TweetService.svc... Select PUT as the HTTP verb for this request...

UpdateTweet Method Fiddler Start-up

Add call to UpdateTweet's required URI: UriTemplate for the method is /Tweet.

UpdateTweet Method Fiddler UpdateTweet Method URI

Specify the request Header: Content-Type: application/json.

Now, we have come to the most important bit! specifying the message body - the data that is to be UPDATED via the UpdateTweet method!

Let's Update Tweet with Id: 2 to the following:

C#
{
  "Id": 2,
  "PostedBy": "UPDATED via Fiddler",
  "Text": "UPDATED tweet via Fiddler"
}

UpdateTweet Method Fiddler UpdateTweet Method Request Body

Time to Execute our Update Request!

And under the Inspectors Tab - our response header of 200 indicates all has been ended well! the record has been updated!

UpdateTweet Method Fiddler UpdateTweet Method Response Header

A quick call to GetTweets method returns the newly Updated Tweet!

GetTweets after UpdateTweet Execute

Time to test our DeleteTweet method: DeleteTweet is decorated with Web Invoke attribute that accepts a HTTP DELETE verb request.

DeleteTweet Method

Fire-up Fiddler...

Go to Composer... Enter the address of TweetService.svc... Select DELETE as the HTTP verb for this request...

DeleteTweet Method Fiddler Start-up

Add call to DeleteTweet's required URI: UriTemplate for the method is /Tweet/{deleteTweetId}.

We will be deleting Tweet with Id: 2 (the one we updated in the previous step) NOTE - in the URI, we have simply specified Tweet Id at the end! ...theURI.../2...

DeleteTweet Method Fiddler DeleteTweet Method URI

Note* As per HTTP specifications - with DELETE and GET Verbs, we are not required to send a request body! Needless to add, REST follows this specification.

Time to click Execute!

The result: we get a response of 200 - Tweet with Id: 2 has been deleted!

DeleteTweet Method Fiddler Result

A quick call to GetTweets method returns the remaining Tweet(s)!

GetTweets after DeleteTweet Execute

Note in the result displayed above Tweet with Id of 2 is missing because we have successfully deleted it!

With this, we have completed our quick tests for TweetService.svc and have established that it works well!

It is now time for us to create a client for our TweetService.svc. We will do this in the next section.

Creating and Testing WCF RESTFul Web Service Client

Fiddler was good for some quick unit testing. Now it's time to build our own web service client. Let us start by adding a new Console Application Project called TweetClient which will be the client that will consume our RESTFul Tweet Web Service.

TweetClient Project - Screen-Shot

TweetClient Project Added - Screen-Shot

As WSDL is not generated for the RESTFul service, we have no luxury of default service proxy class, etc... by just introducing service reference.

We would have to do all the required serialization, de-serialization, network calls, creating data transport objects ourselves for consuming our RESTFul Tweet Web Service.. it sounds bad but hang in there as it is very simple to do so in .NET!

Let's create a folder Services and introduce a class called TweetService that will do all the talking for our web client...

TweetClient Project - Services Folder and TweetService Client Screen-Shot

Introducing the GetTweets method!

TweetClient Project - GetTweets missing transport object Screen-Shot

Ok.. so we do not have the definition for Tweet! Let us fix that first...

Let's create a folder Transports and introduce a class called Tweet that will basically be clients Tweet object definition...

TweetClient Project - Transports Folder and Tweet Object Screen-Shot

The definition of our client side Tweet object will not be much different to the one that we have declared in TweetBL project!

TweetClient Project - Transports Folder and Tweet Object Definition Screen-Shot

Adding the reference to Tweet Object in our Transports folder.. all good now!

TweetClient Project -  GetTweets added transport object Screen-Shot

Now, getting back to the GetTweets method...

In GetTweets method, we will employ a Web Client and will request the Web Server to pass us data in JSON format.

Below is the definition for GetTweets method - Note it has appropriate documentation for explanation:

C#
public IList<Tweet> GetTweets()
{
     // Making a call to our GetTweets Endpoint by employing a WebClient!
     var client = new WebClient();
     
     // Requesting JSON from the Web Server - because we have deserializer for JSON in place
     client.Headers.Add("Accept", "application/json");
     
     // Using WebClient we can download a file, a string etc.. we will download String
     // because we will be receiving the data from our TweetService.svc in XML format or JSON format
     // ...all we have to do than is create a deserializer to create a object from that 
     // received XML/JSON data! .. sweet
     
     // to download a string we need to give the web address of our service endpoint
     // below I have specified the local address and the correct endpoint to access the
     // required information
     var result = client.DownloadString("http://localhost:47354/TweetService.svc/GetTweets");            
     
     // Now we will employ the JSON desiralizer that comes with .NET to de-serialize and 
     // create a Tweet object for us from the response received from TweetService.svc
     var serializer = new DataContractJsonSerializer(typeof(List<Tweet>));
     
     List<Tweet> resultObject;
     using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(result)))
     {
         resultObject = (List<Tweet>)serializer.ReadObject(stream);
     }
     
     return resultObject;
}

Screenshot of GetTweets method:

TweetClient Project -  GetTweets Method : DataContractJsonSerializer missing-  Screen-Shot

Oops - the red squiggly lines of death!... it is complaining about DataContractJsonSerializer... let's add the reference and fix it!

Adding reference to: System.Runtime.Serialization to get access to DataContractJsonSerializer.

Note* the reference has been added in TweetClient Project.

TweetClient Project -  Add reference to  System.Runtime.Serialization.Json Take 1 Screen-Shot

TweetClient Project -  Add reference to  System.Runtime.Serialization.Json Take 2 Screen-Shot

TweetClient Project -  Add reference to  System.Runtime.Serialization.Json Take 3 Screen-Shot

and the problem has been fixed!

TweetClient Project -  Add reference to  System.Runtime.Serialization.Json Take 4 Screen-Shot

Time to run our GetTweets method.

Follow the steps mentioned below:

Step 1: Set Tweet.WCFService.RESTful as the Default Start Up Project.

Step 2: Double click on TweetService.svc in Tweet.WCFService.RESTful.

Step 3: Go to Debug (in Menu Options) and select Start without Debugging.

Step 4: Your default browser will display the following page!

Tweet.WCFService.RESTful-  Running without Debugging Screen-Shot

Step 5: Jump to TweetClient Project.

Step 6: Select TweetClient Project, right click and follow the screen-shot below.

TweetClient Project-  Running Program Class Take 1 Screen-Shot

Note* I will leave Program Class in TweetClient Project for you to explore on your own! as it doesn't house any article related code. All it has is a fancy GUI (you decide :)) to invoke our RESTFul Tweet Service!

After following Step 6 - the result of our labour:

TweetClient Project-  Running Program Class GUI Take 1 Screen-Shot

Select L (press enter) to List all Tweets - It calls our GetTweets method:

TweetClient Project-  Running Program Class GUI Call to List all Tweets - Which wil fail Screen-Shot

Boom... we have an exception! The exception is thrown in GetTweets method of TweetClient project.

TweetClient Project-  Running Program Class GUI Call to List all Tweets FAILS: Exception Reported- Which wil fail Screen-Shot

Let's have a closer look at the exception.

Setting breakpoints at line 39 and 45 of TweetService class in TweetClient project.

TweetClient Project-  TweetService.cs with set Breakpoints lines 39 and 45 Screen-Shot

Running the TweetClient Project again.. to explore the condition of our application at set breakpoints...

Note* remember to type in L when the GUI pops up and press enter!

Press F10 when the execution reaches line 39 and once it is on line 45, point the cursor to variable result on line 39... we need to look at what is stored in variable result in JSON visualizer... follow the steps below:

TweetClient Project-  TweetService.cs line 39 Screen-Shot

There once we select JSON visualizer... the problem becomes a bit apparent!

TweetClient Project-  TweetService.cs line 39 JSON Visulaizer Screen-Shot

The highlighted warning message clearly states the issue... We have requested JSON format but the web server has not complied to our request!

And because the result returned is not in JSON format, our client fails to deserialize it.

Now to fix this, we need to make a change in our Tweet.WCFService.RESTful project..

We need to make our RESTFul TweetService.svc a bit more flexible so that it can take input from its clients about what sort of format they would like for the results to be returned in..

We can achieve this on an application level by modifying our Web.config file for Tweet.WCFService.RESTful project...

Making the change to Web.config file!

Adding automaticFormatSelectionEnabled will enable our service clients to specify the format of the returned data... by default, web server was returning XMLformat and hence our TweetClient project GetTweets method threw exception because it requested JSON format and was operating on the premise that the server will comply with its request... well, now it will!!

Tweet.WCFService.RESTful Project - Web.config file modified Screen-Shot

Now, here we are, let's follow the above mentioned 6 steps again to test our GetTweets method:

And yes, remember to remove the breakpoints we added... trust me, it will all work out this time :)

Once the 6 steps are followed, we get the following result this time (after selecting L):

TweetClient Project - GetTweets Method Result Screen-Shot

Volla: all the tweets on record have been returned..! Our GetTweets method has finally delivered!

Now, moving on to the remaining methods.

Testing GetTweetByID method...

For this GetTweetByID method, we will request for and de-serialize XML instead of JSON.

The GetTweetByID method:

TweetClient Project - GetTweetById Method Screen-Shot

Testing the method - Now, please follow the above mentioned 6 steps again to test our GetTweetById method

Once the program is running, follow the steps below:

Select L to get the list of all current stored tweets.

TweetClient Project - GetTweetById Method Run Step 1 Screen-Shot

Type in 1 to pull the tweet with Tweet Id of 1...

arr... more trouble...

TweetClient Project - GetTweetById Method Result Exception Screen-Shot

If we View Detail on the thrown exception:

TweetClient Project - GetTweetById Method Result Exception detail Screen-Shot

To fix this.. we need to introduce our XML Schema definition that we have defined in TweetBL project Tweet class.

So, in Tweet Class in Transports folder of Tweet client project, add the following line...

TweetClient Project - Transport Project Tweet Client XML Definition addition Screen-Shot

Now run the test again... the final result...

TweetClient Project - GetTweetById Method Result Screen-Shot

Time to move onto Create Tweet Method.

No unfortunately with WebClient, you cannot tell which HTTP verb to use for your service operation. Web Client uses GET HTTP Verb for all of its requests.

As we desire more control when it comes to Create/Update Tweet, we would now need to employ HTTP Web Request and not Web Client as it will provide us with the ability to use other HTTP Verbs for our requests.

The CreateTweet method:

TweetClient Project - CreateTweet Method 1 Screen-Shot

TweetClient Project - CreateTweet Method 2 Screen-Shot

Time to Test CreateTweet method

Follow the 6 steps (mentioned above) and then follow the steps mentioned below:

Type in N - for entering New Tweet...

TweetClient Project - CreateTweet Method Test 1 Screen-Shot

TweetClient Project - CreateTweet Method Test 2 Screen-Shot

Type in L and here is the result:

TweetClient Project - CreateTweet Method Test 3 Screen-Shot

Time to Write and test out Update method

Update method just has one difference when compared to CreateTweet method and that is the HTTP Verb that it uses...

Update method requires the use of PUT HTTP Verb.

Update method:

TweetClient Project - UpdateTweet Method Screen-Shot

Testing Update method - Follow the 6 steps (provided above) along with the ones specified below...

Retrieving the Tweet we saved employing the CreateTweet method...

TweetClient Project - UpdateTweet Method Test 1 Screen-Shot

Select the Option E to Edit:

TweetClient Project - UpdateTweet Method Test 2 Screen-Shot

Select L to List all Tweets...

TweetClient Project - UpdateTweet Method Test 3 Screen-Shot

The final result... updated Tweet!

TweetClient Project - UpdateTweet Method Test 4 Screen-Shot

Now, the last method - the DeleteTweet method!

For Delete, we want to send an Object that is not a Tweet Object but has the Tweet Id attribute in it...

Adding a New Transport Object in TweetClient Project.. which will have the required definition of the object we desire to use for DeleteTweet operation!

TweetClient Project - Transport Folder Delete Tweet 1 Screen-Shot

TweetClient Project - Transport Folder Delete Tweet 2 Screen-Shot

The DeleteTweet Method:

TweetClient Project - Delete Tweet Method Screen-Shot

Time to Test the DeleteTweet Method

Follow the above mentioned 6 steps and then follow the steps below...

Type in the id of the Tweet we added using CreateTweet method... Select Option D to Delete it...

TweetClient Project - Delete Tweet Test 1 Screen-Shot

Select Y for Yes - Confirming Deletion: Also Type in L to list all tweets...

TweetClient Project - Delete Tweet Test 2 Screen-Shot

The fruits of our Labour.. Tweet with Id 7 has been deleted... the tweets returned does not have the tweet with id 7!

TweetClient Project - Delete Tweet Test 3 Screen-Shot

and we are done!!!!

Final Thoughts

Here is a article on WCF Web Service! Also, here is the link to article on WCF Ajax Web Service!

Both articles are written by me. Both articles are a simple demo of said services demonstrating the power and simplicity of WCF.

It's time for me to sign off. Feel free to ask questions, provide feedback and everything in between as I am on the same boat with you. P.S.: The Boat is called "Burn and Learn".

History

  • Version 1 submitted on 19th April 2015

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)