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



Jobs in Ashburn


Web Developers - Robert Half Technology
.00 per year Sr. C#/SQL .NET Web (REST) Developer up to $130k +10% Bonus - Vienna, VA Job Overview ... development with Asp.Net, Ajax, CSS and...
 
Database Administrators - TierPM AV/IT Talent Solutions
Administrator in the Washington, DC area. The ideal candidate will have at least 5 years of SQL database ... 5-7 years of SQL DBA experience...
 
Computer Software Engineers, Applications - Strongbridge
is a highlyskilled ASP.NET/C# developer with a minimum of 5 years of experience including astrong ... preferred. 4-5 years of experience working...
 
Computer Software Engineers, Applications -
IT .Net Developer (Information Technology – C#/SQL) Job Description We are seeking an ... the concept of modular design IT .Net Developer (...
 
Web Developers - DDL OMNI Engineering
conversion from ASP 3.0 to Microsoft ASP.NET. ... Developer include: ASP.NET SQL Reporting Services ASP Stored Procedures and Scripts JavaScript...






Latest Blogs on Dotnetmentors.com


Hello World Example With AngularJS and ASP.NET MVC
This article equips you to create your first hello world example using AngularJS framework and ASP.NET MVC.
 
How to Use Areas in ASP.NET MVC
This article describe about Areas in ASP.NET MVC application and organize application structure in better and simple way.
 
Explain ASP.Net MVC Routing With Example
This article describes how ASP.NET MVC routing works, Custom Routes, attribute routing, route constraints, Area Routing
 
ASP.NET MVC Application Request life cycle
This article describes about ASP.NET MVC request life cycle, it explains how request
 
Implementing Finalize and Dispose(.NET Framework) in C#
This article describes about implementing between dispose and finalize methods for


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
User profile picture on dotnetmentors.com

by sujil at 7/29/2014 7:16:00 PM
helo
post comment
User profile picture on dotnetmentors.com

by Mehul at 8/19/2014 5:13:00 PM
Hi, I am also facing error "The remote server returned an error: (400) Bad Request." at PlaceOrder(). does setting up value solve the problem maxReceivedMessageSize ?! How/where to set maxReceivedMessageSize in web.config?
post comment
User profile picture on dotnetmentors.com

by max at 10/29/2014 9:04:00 AM
If I want to just a post a string (128 characters long), which will be parsed at server, how can I pass it? Is it even possible? All I care about post the data which is string.
post comment
User profile picture on dotnetmentors.com

by Laxmikant at 10/30/2014 12:48:00 PM
@Max you can certainly do it ... just make a operation contract which accept a string see below operation contract [OperationContract] [WebInvoke(UriTemplate = "/PlaceOrder", RequestFormat= WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST")] bool PlaceOrder(string ordernumber);
post comment
User profile picture on dotnetmentors.com

by max at 10/31/2014 8:00:00 AM
Thanks Laxmikant for quick response. Is that also possible to pass more than 1 parameter? Also how do I add reference in client when client and service are not in single solution? Is there also a way to pass parameters other than json format? Thanks,
post comment
User profile picture on dotnetmentors.com

by Laxmikant at 10/31/2014 9:32:00 AM
@Max 1. you can have multiple parameters as input with this you also have to configure UriTemplate accordingly number of parameters. 2. You can update the ServiceUrl and call proxy.DownloadData() function which may be or may not be in same solution. 3. You can also have XML as Request / Response format.
post comment
User profile picture on dotnetmentors.com

by max at 10/31/2014 7:03:00 PM
I see that we can also set the property of object as you did in your example and that way i can set additional parameter in the property. So is it possible to pass order object from separate project? Thanks for your help.
post comment
User profile picture on dotnetmentors.com

by max at 11/4/2014 9:46:00 AM
Hi Laxmikant, Any suggestion for my last post? Thanks,
post comment
User profile picture on dotnetmentors.com

by max at 11/4/2014 9:46:00 AM
Hi Laxmikant, Any suggestion for my last post? Thanks,
post comment
User profile picture on dotnetmentors.com

by max at 11/4/2014 9:46:00 AM
Hi Laxmikant, Any suggestion for my last post? Thanks,
post comment