Share via


Walkthrough: Build, Host, and Test Simple RESTful WCF Service

This post summarizes the steps needed to create basic self hosted RESTful WCF service based on the book RESTful .NET: Build and Consume RESTful Web Services with .NET 3.5.

Summary of steps

Following are the summary of steps needed to be taken to create and test self hosted RESTful WCF services.

  • Step1 - Create a class that represent resource – user.
  • Step2 - Create a service that expose functionality to manipulate the resource
  • Step3 - Create self-host to host the service
  • Step4 - Use fiddler to test the solution – get all users
  • Step5 - Use fiddler to test the solution  - get specific user
  • Step6 - Use fiddler to test the solution  - update user

Rest of the post is the details for each step. Create new console project in Visual Studio.

Step1 - Create a class that represent resource – user.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace ReadWriteREST
{
    //SINCE I USE DATA CONTRACT THE SERIALIZED XML WILL BE
    //BUILT BASED ON ELEMENTS vs. ATTRIBUTES
    [CollectionDataContract(Name="users",Namespace="")]
    public class Users: List<User>
    {
    }
    [DataContract(Name = "user", Namespace = "")]
    public class User
    {
        [DataMember(Name = "id", Order = 1)]
        public string UserId;
        [DataMember(Name = "firstname", Order = 2)]
        public string FirstName;
        [DataMember(Name = "lastname", Order = 3)]
        public string LastName;
        [DataMember(Name = "email", Order = 4)]
        public string Email;
    }
}

 

Step 2 - Create a service that exposes functionality to manipulate the resource

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;

namespace ReadWriteREST
{
    [ServiceContract]
    public class UserService
    {
        static Users _users = new Users();

[WebGet(UriTemplate = "/users")]
        [OperationContract]
        public Users GetAllUsers()
        {
            GenerateFakeUsers();
            return _users;
        }

        [WebInvoke(UriTemplate = "/users", Method = "POST")]
        [OperationContract]
        public User AddNewUser(User u)
        {
            u.UserId = Guid.NewGuid().ToString();
            _users.Add(u);
            return u;
        }

 

        [WebGet(UriTemplate = "/users/{user_id}")]
        [OperationContract]
        public User GetUser(string user_id)
        {
            var u = FindUser(user_id);
            return u;
        }

        private User FindUser(string user_id)
        {
            return new User() { FirstName = "alik",
LastName = "levin",
Email = "alikl@microsoft.com",
UserId = "1" };
        }

        private void GenerateFakeUsers()
        {

            _users.Add(new User() { FirstName = "alik",
LastName = "levin",
Email = "alikl@microsoft.com",
UserId = "1" });
        }
    }
}

Step 3 - Create self-host to host the service

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace ReadWriteREST
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost sh = new ServiceHost(typeof(UserService),
                                             new Uri("https://localhost:8089/"));
            bool openSucceeded = false;
            //TRY OPENINNG, IF FAILS THE HOST WILL BE ABORTED
            try
            {
                ServiceEndpoint sep = sh.AddServiceEndpoint(typeof(UserService),
                                                            new WebHttpBinding(),
                                                            "Hosting");
                sep.Behaviors.Add(new WebHttpBehavior());
                sh.Open();
                openSucceeded = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Service host failed to open {)}",
ex.ToString());
            }
            finally
            {
                if (!openSucceeded)
                {
                    sh.Abort();
                }
            }
            if (sh.State == CommunicationState.Opened)
            {
                Console.WriteLine("The Service is running. Press Enter to stop.");
                Console.ReadLine();
            }
            else
            {
                Console.WriteLine("Server failed to open");
            }
            //TRY CLOSING, IF FAILS THE HOST WILL BE ABORTED
            bool closeSucceed = false;
            try
            {
                sh.Close();
                closeSucceed = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Service failed to close. Exception {0}",
ex.ToString());
            }
            finally
            {
                if (!closeSucceed)
                {
                    sh.Abort();
                }
            }
        }
    }
}

Step 4 - Use fiddler to test the solution – get all users

This functionality is handled by the following method:

[WebGet(UriTemplate = "/users")]
[OperationContract]
public Users GetAllUsers()

Run your service. Use Fiddler’s Request Builder to issue a request similar to the following

RESTful WCF

Use Inspectors tab to review the response.

Step 5 - Use fiddler to test the solution  - get specific user

The functionality is handled by the following method

[WebGet(UriTemplate = "/users/{user_id}")]
[OperationContract]
public User GetUser(string user_id)

RESTful WCF

Use Inspectors tab to verify the response.

Step 6 - Use fiddler to test the solution  - update user

The functionality is handled by the following method:

[WebInvoke(UriTemplate = "/users", Method = "POST")]
[OperationContract]
public User AddNewUser(User u)

RESTful WCF

Notice three main attributes of this request:

  • the method is POST although submitted to the same URL.
  • Content-Type is text/xml.
  • Request body contains serialized User object as the method expects.