CRUD Operations using WCF RESTful Service – Part 1

By | January 8, 2014


REST (Representational State Transfer) is basically an architectural style that is based on the same principles as that of “Web”. In this WCF Service tutorial we are going to see these web principles in action. We will be using standard HTTP verbs for CRUD (Create, Retrieve, Update, Delete) operations, HTTP Content-Types etc.In one of my previous articles, I explained 5 simple steps to create your first RESTful web service. In part-1 of this article, we will build a RESTful web serviceusingWCF while in second part, we will be consuming the web service using jQuery.Let’s start by creatingaWCF Service Application project using Visual Studio. Beforecreatingactual service, lets prepare object that represents data in our application.Following is the code forourDataContract class i.e. “Book”.

 [DataContract]
 public class Book
 {
          [DataMember]
          public int BookId { get; set; }   
          [DataMember]
          public string Title { get; set; }
          [DataMember]
          public string ISBN { get; set; }
}

For the purpose of simplicity, we are not going to write code for interacting with database. Instead we will separate code for actual CRUD operations using repository design pattern. Benefit of using repository pattern approach is that we can easily replace the implementation with actual database interaction code according to our own need.

We will create an interface “IBookRepository” and a class “BookRepository” as follows:

 public interface IBookRepository
 {
           List GetAllBooks();
           Book GetBookById(int id);
           Book AddNewBook(Book item);
           bool DeleteABook(int id);
           bool UpdateABook(Book item);
 }

public class BookRepository : IBookRepository

 {
     private List<Book> books = new List<Book>();
     private int counter = 1;

public BookRepository()

     {
           AddNewBook(new Book { Title = “Thinking in C#”, ISBN = “65674523432423″ });
           AddNewBook(new Book { Title = “Thinking in Java”, ISBN = “34223434543423″ });
           AddNewBook(new Book { Title = “Beginning WCF”, ISBN = “35343532423″ });
     }
//CRUD Operations
  //1. CREAT
   public Book AddNewBook(Book newBook)
   {
         if (newBook == null)
                  throw new ArgumentNullException(“newBook”);         newBook.BookId = counter++;
         books.Add(newBook);
         return newBook;
   }//2. RETRIEVE /ALL
   public List GetAllBooks()
   {
          return books;
    }   //2. RETRIEVE /By BookId
   public Book GetBookById(int bookId)
   {
          return books.Find(b => b.BookId == bookId);
    }

    //3. UPDATE
    public bool UpdateABook(Book updatedBook)
    {
           if (updatedBook == null)
                  throw new ArgumentNullException(“updatedBook”);

           int idx = books.FindIndex(b => b.BookId == updatedBook.BookId);
           if (idx == -1)
                       return false;

            books.RemoveAt(idx);
            books.Add(updatedBook);
            return true;
     }

     //4. DELETE
     public bool DeleteABook(int bookId)
     {
             int idx = books.FindIndex(b => b.BookId == bookId);
             if (idx == -1)
                  return false;

             books.RemoveAll(b => b.BookId == bookId);
             return true;
      }
 }

As we are going to perform CRUD operations using RESTful service, we must know that how these actions map to standard HTTP verbs.

Method
Action
GET
Getting a specific representation of a resource. In our case, get all books or get a book by a specific ID are relevant actions.
PUT
Create/Update a resource. Add a new book or update an existing book.
DELETE
Delete a resource. Delete an existing book.
POST
Submit data to a resource.

Now, its time to add WCF service contract as well as service as follows:

[ServiceContract]
public interface IBookService
{
   [OperationContract]
   [WebInvoke(Method = "GET",
   RequestFormat = WebMessageFormat.Json,
   ResponseFormat = WebMessageFormat.Json,
   UriTemplate = "Books/")]
   List GetBookList();

[OperationContract]

   [WebInvoke(Method = "GET",
   RequestFormat = WebMessageFormat.Json,
   ResponseFormat = WebMessageFormat.Json,
   UriTemplate = "BookById/{id}")]
   Book GetBookById(string id);   [OperationContract]
   [WebInvoke(Method = "PUT",
   RequestFormat = WebMessageFormat.Json,
   ResponseFormat = WebMessageFormat.Json,
   UriTemplate = "AddBook/{id}")]
   string AddBook(Book book, string id);

   [OperationContract]
   [WebInvoke(Method = "PUT",
   RequestFormat = WebMessageFormat.Json,
   ResponseFormat = WebMessageFormat.Json,
   UriTemplate = "UpdateBook/{id}")]
   string UpdateBook(Book book, string id);

   [OperationContract]
   [WebInvoke(Method = "DELETE",
   RequestFormat = WebMessageFormat.Json,
   ResponseFormat = WebMessageFormat.Json,
   UriTemplate = "DeleteBook/{id}")]
   string DeleteBook(string id);
}

Service exposes methods for all CRUD operations. Major things to understand about above code are:

WebInvoke attribute is used to expose services using HTTP verbs like GET, POST, PUT, DELETE etc.

  • Method is the HTTP verb used for a specific action already explained above.
  • RequestFormat is the request message format e.g. JSON, XML etc.
  • ResponseFormat is the response message format e.g. JSON, XML etc.
  • UriTemplate is the unique URI for each specific service operations. Service consumer only knows about unique URI defined in UriTemplate.
Implementation code of BookService for all operations is as follows:
public class BookService : IBookService
{
    static IBookRepository repository = new BookRepository();
    public List GetBookList()
   {
          return repository.GetAllBooks();
   }    public Book GetBookById(string id)
   {
          return repository.GetBookById(int.Parse(id));
   }

    public string AddBook(Book book, string id)
   {
          Book newBook = repository.AddNewBook(book);
          return “id=” + newBook.BookId;
    }

    public string UpdateBook(Book book, string id)
    {
          bool updated = repository.UpdateABook(book);
          if (updated)
                return “Book with id = ” + id + ” updated successfully”;
         else
               return “Unable to update book with id = ” + id;

    }

     public string DeleteBook(string id)
     {
              bool deleted = repository.DeleteABook(int.Parse(id));
              if (deleted)
                    return “Book with id = ” + id + ” deleted successfully.”;
              else
                    return “Unable to delete book with id = ” + id;
      }
 }

Configuration settings for the service given below. I have placed the complete configuration for <system.serviceModel>.

<system.serviceModel>
  <services>
          <service name=”RESTServiceCRUD.BookService”
                            behaviorConfiguration=”serviceBehavior”>
               <endpoint address=””
                                     binding=”webHttpBinding”
                                     contract=”RESTServiceCRUD.IBookService”
                                     behaviorConfiguration=”RESTEndpointBehavior”></endpoint>
           </service>
  </services>
  <behaviors>
       <endpointBehaviors>
              <behavior name=”RESTEndpointBehavior”>
                      <webHttp />
              </behavior>
       </endpointBehaviors>
       <serviceBehaviors>
              <behavior name=”serviceBehavior”>
              <serviceMetadata httpGetEnabled=”true” />
             <serviceDebug includeExceptionDetailInFaults=”false” />
       </serviceBehaviors>
   </behaviors>
</system.serviceModel>

Above configuration is pretty similar like normal WCF service except the following.

  • webHttpBinding is the binding specifically introduced for RESTful services in WCF 3.5.
  • endpointBehavior is “webHttp” for RESTful service.
We are done with implementation of all CRUD operations for a WCF RESTful service. Now, in Part-2 of this WCF tutorial series, we will consume all these operations.
Other Related Tutorials:

Top 10 Interview Questions and Answers Series:


  • http://www.blogger.com/profile/04086872350082466529 Connors Joseph

    i want this service to be tested with a browser guide me.
    my config file giving error when i change the binding cofig to web

    pls correct me.

    • http://www.blogger.com/profile/10867674357364468276 Imran Ghani

      Dear Joseph,
      Please given details of error. Actually, your message has a lot of empty spaces.