When we developed our OData web service we came accross a situation in which we needed our webservice to return JSON in stead of XML. According to the specification OData supports both JSON and XML by including the $format query option. Unfortunately WCF Data Service does not support the $format query option and will return the following error when this query option is provided:
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <code /> <message xml:lang="en-US"> The query parameter '$format' begins with a system-reserved '$' character but is not recognized. </message> </error>
The service tells you that it indeed saw the $format query option but that it didn't recognize it as a valid query option. In this blog post I'm going to show you the different options you have for resolving this little problem.
Enable support for the $format query option
Although WCF Data Service does not support the $format query option it actually supports JSON as an output format. All you need to do is specify "application/json" in the Accept header of your request, but sometimes it is not easy to modify the request headers and sometimes you just want to built an OData compliant data service that supports the $format query option. The basic solution to this problem comes down to removing the $format query option and changing the Accept header to application/json.
You don''t have to do this all by yourself. There are two pieces of code out there that do the job for you:
Both of these pieces of code comes with the nice advantage that they also add support for JSONP callbacks. JSONP is a technique commonly used to circumvent the same origin policy of modern browsers. The same origin policy prevents scripts running on domain1.com to communicate with domain2.com.
Using the DataServicesJSONP library is very simple. You just need to add the JSONPSupportBehaviour to your data service definition, just like in the picture below and you have full support for JSON and JSONP in your OData web service.
Using the WCF Data Services Toolkit not only gives you support for JSON and JSONP, but also adds caching capabilities and offers solutions for a lot different data sources. To use the toolkit in your data service, simply inherit your service from ODataService instead of DataService, just like in the picture below and you have full support for JSON and JSONP in your OData web service.
I created a solution that contains examples of both techniques. You can download it here. The solution contains two wcf services, one that uses DataServicesJSONP and one that uses the toolkit. To compile the code you need to have SQL Compact Edition 4.0 installed. You can install it via the Web Platform Installer or directly via the Microsoft Download Center.
The last couple of months I've been working on my bachelor project to finish my bachelor computer science. Together with Tom Verhoeff, Jos Kraaijeveld, Jochem Toolenaar and Oana Nitu, I participated in the Imagine Cup 2011. We formed team O!ife and our project was called the City Cloud. The City Cloud is a cloud computing platform that allows different kinds of data generated by the city, its inhabitants, companies and its government to be easily accessed by developers to create new innovative technologies and solutions. You can find more about the City Cloud on the O!ife blog.
This post is one in a series on how we built the City Cloud and everything around it. The focus of these posts will be on the technical aspects of the City Cloud. It will also cover some problems we encountered during development and the solutions we used to tackle them. At this moment I have no idea how many parts will follow. We've came across lots of different problems and used lots of technologies, so I will write another part whenever I have the time and when I think the topic is interesting enough for other developers. The first part will cover the overall architecture of the system to establish a background for other posts.
When we started the City Cloud project we thought of it as a developer platform for a city. The main goal should be to offer the correct tools for developers to build next generation ubiquitous applications: it should be easy to expose new datasets through the system and the development of applications using these datasets should not require large investments in both terms of infrastructure and programming skills.
In the design phase we divided the system up into three parts: the cloud framework, the mobile platform and the website/webapplication. The framework was the heart of the system and was designed to run in the Azure cloud. Its responsibility was to present the data that is part of the system in an easy and consistent way and offering an all-in-one solution for data and app storage. The mobile platform and the website/webapplication functioned as two different portals to the data and the apps. The website should give general information on cities and should show the datasets and applications available. It should also provide developers with documentation and best practices on how to make use of the platform's capabilities in the best possible way. The mobile framework should be the main portal to the end user in a city. It should give an user specific information on data and apps based on his current location. With more and more smartphones sold every day, smartphones offered a great opportunity to be the number one entry point to the City Cloud.
The framework should expose data in an easy way. To achieve this we decided to go with an OData webservice running in an Azure webrole. Besides being a Microsoft technology which counts for the Imagine Cup, OData offers an excellent way to expose datasets and besides that offers great possibilities to perform transformations and filtering on the returned data. Another advantage is the great tools available to develop OData webservices and to consume them on almost all major platforms. To get data into the City Cloud framework we invented "connectors". To expose a new dataset through the framework all a developer would need to do is build a connector that allows the City Cloud to retrieve data from their data source. This connector should implement some interface, provide the system with some description of the data structures and it should all magically come to life.
Website and webapplication
To give developers and users an overview of the data and applications already in the system we built the website including a Silverlight webapplication. The webapplication was meant to be used as an explorer for the webservice. In this way everybody could take a quick look into the system to browse data. It also offered the possibility to plot these datasets on a map.
Developers could use the website to submit new applications and new connectors to the system. Because of the extensibility model we felt the need to building a validation step to verify the working of the newly submitted parts in the framework. To validate new submissions we made use of a core feature of the azure platform: a worker role. In Windows Azure a worker role is meant to be used for background processing or other long running tasks. In the cloud framework we used a worker role to validate a submission and to make the required changes to the framework to add a new connector or building block.
At the end of the design phase the overall system architecture looked a lot like a high level Model-View-Controller architecture. The website and the mobile platform functioned as the views, while the framework holds the current state of the system and functioned as the model. The worker role was used to change the state of the framework and can thus be seen as the controller. The following image shows the high level architecture in a graphical way:
I hope this gives a good overview of the system we built the last couple of months. Unfortunately no code yet, but I will save that for the next part.