While working with my client, I run into a problem with large file uploading using WCF-JSON. Here i am demonstrating the problem and solution through this article. The article also demonstrates step by step JSON communication using WCF.
Following are the experiments using WCF REST Service with JSON:
- Invoking a method and getting string as return parameter
- a string to method and getting class as return parameter
- a class as method argument and receiving Boolean
- large file as method argument
What is REST?
REST stands for Representational State Transfer and is an architectural style. It was developed in parallel with HTTP/1.1. In short REST is an architectural style that exploits the existing web protocols and technologies. REST provides an easier way of data access comparing with the SOAP protocol. REST and SOAP relies on HTTP protocol. While considering interoperability of WCF with other platforms like Android REST is considered to be a good solution.
REST provides an alternative to SOAP and WSDL. REST on Web Services has evolved in big numbers for the last few years. Thomas Roy Fielding, the principal author of HTTP specification described REST as the key architectural principle of World Wide Web.
One of the key characteristics of a RESTful Web service is the explicit use of HTTP methods (GET, POST, PUT, DELETE) in a way that follows the protocol as defined by RFC 2616. But in the case of SOAP, POST is used to achieve all the cases.
Examples are given below:
|
Method |
Description |
Example |
SOAP (WS-*) Equivalent
|
|
GET |
Retrieve
an Item |
GET
/books/101 |
POST
endpointInvoke
GetOrder(101); |
|
POST |
Place
an Item |
POST /books
<book>
<id>102</id>
<name>Book 2</name>
<author>Author 2</author>
<price>0</price>
</book> |
POST
endpointInvoke
InsertOrder(order); |
|
PUT |
Modify
an Item |
PUT
/book/101 |
POST
endpoint
Invoke
UpdateOrder(order); |
|
DELETE |
Delete
an Item |
DELETE
/books/101 |
POST
endpoint
Invoke
DeleteOrder(101); |
Passing argument to the service through url makes the service invocation through browser address bar.
What is JSON?
JSON represents JavaScript Object Notation and is an open standard lightweight data interchange format in human readable form. Shortly, it is a data representation format.
JSON provides a simple alternative to the Fatty XML format of data representation. For example a class with properties name and age can be represented as:
{
”name”: ”Jack”,
“address”:”Number, Street”
”age”: 25
}Advantages of WCF with JSON
WCF supports JSON formatting and we can achieve it by adding attributes to the operation contracts.
In the case of Web Services, the only protocol supported was SOAP. SOAP in turn relies on HTTP protocol. WCF supports more protocols and serves good advantage over Web Services. The System.Runtime.Serialization assembly contains the JSON formatters.
Applications Involved
There are 2 applications created for this article:
- ServiceApp representing the service application with WCF, REST and JSON
- ClientApp representing a windows application consuming the service
Before proceeding with the steps below, you need to create a solution with a WCF Service Application (ServiceApp) and Windows Forms Application (ClientApp). Now Add reference to System.Runtime.Serialization for the ClientApp.
The application contains code snippets for the following REST/JSON scenarios:
- Invoking a method and getting string as return parameter
- a string to method and getting class as return parameter
- a class as method argument and receiving Boolean
- large file as method argument
The solution explorer looks like below:
Make sure you changed the startup projects to both of them in the solution properties.
Replace the web.config of Service application with the following content of web.config attached.
Step 1: Receiving string through JSON
Create a new method in the IService interface as following:
[OperationContract]
[WebInvoke(Method="GET", UriTemplate="/GetData", RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json)]
string GetData();
The above method returns one string on invoking. Implement the method in the Service class file as following:
public string GetData()
{
return "Data from Service";
}On executing the application, we can invoke the method from the browser address bar itself using the url: http://localhost:11523/Service1.svc/GetData. We will be getting the Open With dialog box and opening in Notepad, we can see the string “Data from Service”.
The above invocation was through the browser. Inorder to access the content through a .Net application we have to do some additional amount of work.
- Create WebClient instance
- Format any parameters
- Invoke the Method using Url
- Unformat the received values
In the ClientApp create a button and on the click of it write the following code:
WebClient client = new WebClient();
byte[] data = client.DownloadData("http://localhost:11523/Service1.svc/GetData");
Stream stream = new MemoryStream(data);
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(string));
string result = obj.ReadObject(stream).ToString();
MessageBox.Show(result);On executing the application we can see the following result.

Step 2: Receiving class through JSON
Now we can use the GET HTTP verb to return a Type using JSON. The input argument is an id in string. The method information is given below:
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetEmployee/{id}",
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
Employee GetEmployee(string id);
Here we have to additional plumbing work to deserialize the received JSON Employee object. The code is given below:
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(Employee));
Employee result = obj.ReadObject(stream) as Employee;
Step 3: Posting Typed Argument and returning Boolean
Here we are using the POST method to upload an Employee object. The service will be saving it and returning a Boolean.
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/SaveEmployee",
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
bool SaveEmployee(Employee employee);Step 4: Sending large file through JSON
Now we can try with sending file with JSON. The default endpoint behavior restricts maxReceivedSize as 65536. This does not allows larger file uploads. In our test application the endpoint behavior is modified to accommodate upto 2147483647 bytes of data. The sample application tests 10 MB file upload through REST and JSON formatting.
Modified Configuration
Following is the modified configuration section for the service part.
<webHttpBinding>
<binding name="StreamedRequestWebBinding"
bypassProxyOnLocal="true"
useDefaultWebProxy="false"
hostNameComparisonMode="WeakWildcard"
sendTimeout="10:15:00"
openTimeout="10:15:00"
receiveTimeout="10:15:00"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="StreamedRequest">
<readerQuotas maxArrayLength="2147483647"
maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>The configuration section has to be modified as the default WCF binding does not support large file size handling.
Client Application
Following is the screen shot for the Client application.

Note
The REST/JSON service receiving code is not as friendly as the usual WCF service invocation code using Proxy. Still we can use Generics Methods to wrap the receiving code to make accessing the methods easier.
References
- http://msdn.microsoft.com/en-us/library/ms730294.aspx
- http://www.json.org/fatfree.html
- http://debugmode.net/2011/05/15/wcf-rest-service-with-josn-data/
- http://www.ibm.com/developerworks/webservices/library/ws-restful/
- http://en.wikipedia.org/wiki/Roy_Fielding
- http://myarch.com/json-pros-and-cons
Summary
In this article we have seen about the advantages of REST enabled WCF services along with examples. The JSON formatting was explored with string, class and large file uploading. Using the associated application you can see the actual service invocations for the above mentioned 4 scenarios.
Source Code
You can download the source code here.