Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

CRUD Operations using WCF RESTful Service - Part 1

4.08/5 (9 votes)
8 Jan 2014CPOL3 min read 32.7K  
Crude operations using WCF RESTful Service

Introduction

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 service using WCF while in the second part, we will be consuming the web service using jQuery.

Let's start by creating a WCF Service Application project using Visual Studio. Before creating actual service, let's prepare object that represents data in our application.

Following is the code for our DataContract class i.e., "Book".

C#
[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:

C#
public interface IBookRepository
 {
     List<Book> 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<Book> 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, it's time to add WCF service contract as well as service as follows:

C#
[ServiceContract]
public interface IBookService
{
    [OperationContract]
    [WebInvoke(Method = "GET",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json,
                UriTemplate = "Books/")]
    List<Book> 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 the 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:

C#
public class BookService : IBookService
 {
 static IBookRepository repository = new BookRepository();
public List<Book> 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>.

XML
<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" />
 </behavior> 
 </serviceBehaviors>
 </behaviors> 
 </system.serviceModel>

The 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 that Might Be Of Interest

License

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