WCF rest service to get post JSON data and retrieve JSON data with DataContract

In this article I will talk about creating WCF RESTful services for CRUD operations which uses JSON and DataContracts. CRUD operations are done by http verbs GET, POST, PUT and DELETE.

Introduction to REST

REST stands for Representational State Transfer. It provides you an architectural principles about how client and service can exchange the resources over http. REST services can be accessed by any language which support http communication and help truly to heterogeneous applications. As it is sessionless, stateless resource based mechanism it significantly reduces message size and increases performance. It provides REST API for CRUD operations and transfers JSON, XML or both. See more details on RESTful CRUD operations using ASP.NET Web API.



Introduction to JSON

JSON stands for JavaScript Object Notation. It is lightweight data exchange format. It does not create lengthy tags like XML and produce human readable clean data. JSON is completely language independent. It gives you a collection of Name/value pair. The data member names must be a valid JSON string and included in quotation marks or apostrophes. If you are not using reserved JavaScript keyword you may omit the quotation marks or apostrophes.

Follow below steps to implement WCF RESTful service with JSON and DataContract

  1. Create WCF RESTful service

    Follow the article how to create wcf restful services to understand what is RESTful services, when to use which http verbs and nature of RESTful services.
  2. Create Orders DataContract for your RESTful OrderService

    Create a DataContract Orders which will be used for exchanging orders information between service and client. Add below OrderData contract to the RESTfulWCFService application created in previous step.
        using System.Runtime.Serialization;
    
        namespace RESTFulWCFService
        {
            [DataContract]
            public class OrderContract
            {
                [DataMember] 
                public string OrderID { get; set; }
    
                [DataMember] 
                public string OrderDate { get; set; }
    
                [DataMember] 
                public string ShippedDate { get; set; }
    
                [DataMember] 
                public string ShipCountry { get; set; }
    
                [DataMember] 
                public string OrderTotal { get; set; }
            }
        }
                
  3. Orders data store

    Download Orders xml file and put it in C: drive. The CRUD operations will be performed on this xml file using REST calls.
  4. REST OrderService

    Add OrderService to your application. Right click on RESTFulWCFService application from solution explorer -> Select Add -> Select New Item -> Select WCF Service -> Name it as OrderService.
    It will add two files OrderService.svc and IOrderService.cs
  5. Order ServiceContract

    Open IOrderService ServiceContract. Add below OperationContracts to OrderService with WebGet or WebInvoke to make the service as RESTful.
    Notice following attributes for WebGet or WebInvoke
    • UriTemplate: The corresponding Operation will be served with matching Uri.
    • RequestFormat: Tells the format of request is XML or JSON.
    • ResponseFormat: Tells the format of response is XML or JSON
    • Method: WebInvoke has the Method attribute. The value for this could be PUT, POST, DELETE. WebGet does not have this attribute as it is used only for http verb GET.
        using System.ServiceModel.Web;
    
        namespace RESTFulWCFService
        {   
            [ServiceContract]
            public interface IOrderService 
            {
                [OperationContract]
                [WebGet(UriTemplate = "/GetOrderTotal/{OrderID}",
                    ResponseFormat= WebMessageFormat.Json)]
                string GetOrderTotal(string OrderID);
    
                [OperationContract]
                [WebGet(UriTemplate = "/GetOrderDetails/{OrderID}", 
                    RequestFormat=WebMessageFormat.Json,            
                    ResponseFormat = WebMessageFormat.Json)]
                OrderContract GetOrderDetails(string OrderID);
    
                [OperationContract]
                [WebInvoke(UriTemplate = "/PlaceOrder", 
                    RequestFormat= WebMessageFormat.Json,   
                    ResponseFormat = WebMessageFormat.Json, Method = "POST")] 
                bool PlaceOrder(OrderContract order);
            }
        }
                
  6. Order ServiceContract implementation

    Open OrderService.cs and implement operations from IOrderService.
    • GetOrderTotal: method is WebGet operation for getting OrderTotal of particular OrderID.
    • GetOrderDetails: method is WebGet operation for getting Order Details of particular OrderID. It takes the OrderID and returns corresponding OrderDetails in form of OrderContract DataContract.
    • PlaceOrder: method is WebInvoke operation and performs the Create of CRUD operations. It takes OrderContract as input parameter and add its details to Orders.xml
    using System.Xml.Linq;
    using System.Collections;
    
    namespace RESTFulWCFService
    {    
        public class OrderService : IOrderService
        {
            public string GetOrderTotal(string OrderID)
            {
                string orderTotal = string.Empty;
    
                try
                {
                    XDocument doc = XDocument.Load("C:\\Orders.xml");
    
                    orderTotal =
                    (from result in doc.Descendants("DocumentElement")
                    .Descendants("Orders")
                        where result.Element("OrderID").Value == OrderID.ToString()
                        select result.Element("OrderTotal").Value)
                    .FirstOrDefault<string>();
    
                }
                catch (Exception ex)
                {
                    throw new FaultException<string>
                            (ex.Message);
                }
                return orderTotal;
            }
    
            public OrderContract GetOrderDetails(string OrderID)
            {
                OrderContract order = new OrderContract();
    
                try
                {
                    XDocument doc = XDocument.Load("C:\\Orders.xml");
                    
                    IEnumerable<XElement> orders =
                        (from result in doc.Descendants("DocumentElement")
                            .Descendants("Orders")
                        where result.Element("OrderID").Value == OrderID.ToString()
                        select result);
    
                    order.OrderID = orders.ElementAt(0)
                                                .Element("OrderID").Value;
                    order.OrderDate = orders.ElementAt(0)
                                                .Element("OrderDate").Value;
                    order.ShippedDate = orders.ElementAt(0)
                                                .Element("ShippedDate").Value; 
                    order.ShipCountry = orders.ElementAt(0)
                                                .Element("ShipCountry").Value; 
                    order.OrderTotal = orders.ElementAt(0)
                                                .Element("OrderTotal").Value; 
                }
                catch (Exception ex)
                {
                    throw new FaultException<string>
                            (ex.Message);
                }
                return order;
            }
    
            public bool PlaceOrder(OrderContract order)
            {
                try
                {
                    XDocument doc = XDocument.Load("C:\\Orders.xml");
    
                    doc.Element("DocumentElement").Add(
                            new XElement("Products",
                            new XElement("OrderID", order.OrderID),
                            new XElement("OrderDate", order.OrderDate),
                            new XElement("ShippedDate", order.ShippedDate),
                            new XElement("ShipCountry", order.ShipCountry),
                            new XElement("OrderTotal", order.OrderTotal)));
    
                    doc.Save("C:\\Orders.xml");
                }
                catch (Exception ex)
                {
                    throw new FaultException<string>
                            (ex.Message);
                }
                return true;
            }
        }
    }
               
  7. WCF RESTful Service endpoint Configuration

    WCF RESTful Service endpoint Configuration is about similar to normal endpoints. Notice that we are using webHttpBinding.
    We added the endpointBehaviors for webHttp settings. Add below service endpoints.
     <system.serviceModel>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />    
          
          <service behaviorConfiguration="Default" 
                name="RESTFulWCFService.OrderService">
            <endpoint address="" behaviorConfiguration="webBehavior" 
                    binding="webHttpBinding" 
                    contract="RESTFulWCFService.IOrderService" />
            
            <endpoint contract="IMetadataExchange" binding="mexHttpBinding" 
                            address="mex" />
          
          </service>
        </services>
        <behaviors>
            <endpointBehaviors>
                <behavior name="webBehavior">
                    <webHttp helpEnabled="true" />
                </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior name="Default">
                    <serviceMetadata httpGetEnabled="true" />
                </behavior>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
                
  8. View your OrderService

    Right click on OrderService.svc and select View in browser. You may enter the below url in browser
    http://localhost:61090/OrderService.svc/GetOrderDetails/10250
    WCF RESTful Product Service result
    Notice that DataMember attributes are shown in alphabetically order. You may set it using DataMembers Order property. Click here to know more about DataMember and enum member attributes.
  9. Client application for RESTful OrderService

    Add console application to your solution. Add a reference to WCFServices where OrderService is. Add below client code in console application.
    using System.Net;
    using System.Runtime.Serialization.Json;
    using RESTFulWCFService;
    
    namespace DotnetmentorsClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                GetOrderDetails("10248");
                GetOrderTotal("10250");
                PlaceOrder(); 
                Console.ReadKey(true);
            }
    
            private static void GetOrderDetails(string orderID)
            {
                WebClient proxy = new WebClient();
                string serviceURL = 
                        string.Format("http://localhost:61090/OrderService.svc
                                        /GetOrderDetails/{0}", orderID); 
                byte[] data = proxy.DownloadData(serviceURL);
                Stream stream = new MemoryStream(data);
                DataContractJsonSerializer obj = 
                            new DataContractJsonSerializer(typeof(OrderContract));
                OrderContract order = obj.ReadObject(stream) as OrderContract;
                Console.WriteLine("Order ID : " + order.OrderID);
                Console.WriteLine("Order Date : " + order.OrderDate);
                Console.WriteLine("Order Shipped Date : " + order.ShippedDate);
                Console.WriteLine("Order Ship Country : " + order.ShipCountry);
                Console.WriteLine("Order Total : " + order.OrderTotal);
            }
    
            private static void GetOrderTotal(string orderID)
            {
                Console.WriteLine();  
                Console.WriteLine("**** Output for GetOrderTotal ************");  
                WebClient proxy = new WebClient();
                string serviceURL = 
                        string.Format("http://localhost:61090/OrderService.svc
                                        /GetOrderTotal/{0}", orderID);
                byte[] data = proxy.DownloadData(serviceURL);
                Stream stream = new MemoryStream(data);
                DataContractJsonSerializer obj = 
                            new DataContractJsonSerializer(typeof(string));
                string order = Convert.ToString(obj.ReadObject(stream));
                Console.WriteLine(order);
            }
    
            private static void PlaceOrder()
            {            
                OrderContract order = new OrderContract
                {
                    OrderID = "10550",
                    OrderDate = DateTime.Now.ToString(),
                    ShippedDate = DateTime.Now.AddDays(10).ToString(),
                    ShipCountry = "India",
                    OrderTotal = "781"
                };      
          
                DataContractJsonSerializer ser = 
                        new DataContractJsonSerializer(typeof(OrderContract));
                MemoryStream mem = new MemoryStream();
                ser.WriteObject(mem, order);
                string data = 
                    Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
                WebClient webClient = new WebClient();            
                webClient.Headers["Content-type"] = "application/json";            
                webClient.Encoding = Encoding.UTF8;
                webClient.UploadString("http://localhost:61090/OrderService.svc
                                /PlaceOrder", "POST", data);              
                Console.WriteLine("Order placed successfully...");  
            }
        }
    }    
                 

    The client code for Operation PlaceOrder uses POST method which sends JSON data to service. It uses DataContractJsonSerializer to serialize DataContract. We use webClient.UploadString method to post data to service

Download WCFRestFulService application with JSON and DataContract code



Latest Jobs in Ashburn


Computer Software Engineers, Applications - Mindseeker, Inc.
Senior .NET Developer (C#) Permament Position Location: Washington DC L Street Northwest Our client is looking to hire a Senior .NET Developer (C#)....
 
Computer Software Engineers, Applications - Mindseeker, Inc.
Senior SQL Developer - Job Number 1813 Permament Position Location: Washington DC L Street Northwest Our client is looking to hire a Senior SQL...
 
Web Developers - MHM Services, Inc.
MHM Services, Inc. is a privately owned company that contracts with state and local governments to provide staffing, management, and healthcare...
 
Computer Programmers - Precision Systems
C#.NET Developer Our client in Chevy Chase, MD is looking for C#.Net Developers that will work closely with customers, business and technical analysts...
 
Computer Programmers - Precision Systems
Job is located in Fredericksburg, VA. C#.NET Developer Our client in Fredericksburg, VA is looking for C#.Net Developers that will work closely with...






Latest Blogs on Dotnetmentors.com


User Defined Functions in SQL Server
This article talks about user defined functions (UDF) in SQL Server, its benefits, type of UDF and UDF parameters.
 
IIS settings to improve ASP.NET Website Performance
This article helps you to understand required IIS settings to improve ASP.NET Website Performance.
 
ASP.NET Website Performance Improvement Tips
This article give you some of the best tips to improve your ASP.NET Website performance.
 
Getting started with ASP.NET Web API
This article helps you to understand ASP.NET Web API concepts
 
Host ASP.NET Web API in IIS using Visual Studio Publish method
This article will help you to host your ASP.NET Web API in IIS using Visual Studio Publish method. You will use File System publish method for it.


Speak your mind :
Leave a comment for this article on dotnetbloogers.com
User profile picture on dotnetmentors.com

by Robin at 10/15/2013 5:12:00 PM
How to Create WCFRESTFulService with jSon to perform CRUD operations on SQL Server DB . Please forward me example for it on patilrobin420@gmail.com
post comment
User profile picture on dotnetmentors.com

by Laxmikant at 10/15/2013 9:12:00 PM
@Robin, You can use the same methods however you have replace the actual code which talks to your SQL Server through SQLConnection and SQLCommand
post comment
User profile picture on dotnetmentors.com

by jagadish at 12/4/2013 7:02:00 AM
Hi Its a very good example but un fortunately i am getting an error when i post the data it give me error "The remote server returned an error: (400) Bad Request." pls can you help me out
post comment
User profile picture on dotnetmentors.com

by Laxmikant at 12/4/2013 7:37:00 PM
@Jagdish, (400) bad request is generic error it is difficult to provide perfect solution for it. You may try enabling wcf diagnostics by Right click on webconfig->open Edit WCF config manager-> Click on Diagnostics-Right hand pane click on Enable Tracing Note down or specify where the .svclog file should be generated. For more info on WCF Diagnostics and logging http://dotnetmentors.com/how-to-enable-wcf-tracing-and-wcf-message-loging.aspx
post comment
User profile picture on dotnetmentors.com

by siddu at 1/2/2014 7:16:00 PM
PlaceOrder() throws the error "The remote server returned an error: (400) Bad Request."
post comment
User profile picture on dotnetmentors.com

by Laxmikant at 1/3/2014 12:53:00 AM
@Viii, "The remote server returned an error: (400) Bad Request." error comes because client sends data more than set for maxReceivedMessageSize,
Try to change your server side config file and set maxReceivedMessageSize = 65536000
post comment