WCF Data Service V2 and the updated JSON format

In V1 of WCF Data Service (aka ADO.net Data Service), the JSON serialization format for entity sets look like:

{ "d" : [ {entity1}, {entity2} ] }

Where “d” is the “data” wrapper, used as a security measure, and it is defined as the array of elements in the entity set. For example, if you hit a V1 service today, you will see the following response:

  "d" : [ {
    "__metadata": {
      "uri": "$identity",
      "etag": "$etag",
      "type": "$type"
    "NavigationProperty": {
      "__deferred": {
        "uri": "$link"
    "Property" : Value

This format has to be changed in V2 because we now have some additional attributes that are entity-set specific. Specifically, row count and server driven paging skip tokens. We originally thought that we can stuff then inside the data array as the first element and the last element of the array, as this would prevent a change of format. If you have followed our development closely, you would have seen this behavior in the V1.5 CTP1 release. We soon realized that having a mixed type array that sometimes gives the user additional information offers very poor usability. So we finally decided to “upgrade” our JSON format to 2.0, which will let us put the entity set level information where they logically belong to – well, on the entity set.

The new format changes the “d” wrapper from the actual entity array to a new object with multiple properties. The data now lives under “results”, the entity set level information will each become a property in that same object:

  "d" : {
    "results": [ {entity1}, {entity2}, … ],
    "__count": "$count"
    "__next" : "$next-link"

The serialization format for the individual entities stays the same.

To maintain backwards compatibility, the server will only output in the new format if a V2 specified feature had been requested. That is, when the server has to use a DSV=2.0 response (see my post on versioning). For the “normal” V1 requests, the old format will be used.

This does cause some pain when you try to support multiple versions of requests. You now must read the data service version header from the response, and decide which JSON parser you use to retrieve the data.

Comments (2)

  1. Rybolt says:

    Speaking of JSON, how do I get my service to return JSON?  Apparently $format=JSON has been taken out of the framework, no?

  2. $format is a keyword defined in the OData protocol but omitted in the .net implementation (WCF data service). You can send a http header instead:  

    accept: application/json;

    For post/update:

    content-type: application/json