Versioning Protocol of Astoria II

In my previous post on the protocol versioning scheme for Astoria, I’ve explained the two HTTP headers DataServiceVersion and MaxDataServiceVersion. These headers are used by the server and client library to determine how and what to communicate with each other. This mechanism is defined by the Astoria Protocol and our library’s implementation does not require any user interactions. There is no public APIs to give users direct control of mechanism either. In fact, in the most common scenario where the server and the client versions match, one can simply ignore the existence of version control. However, if you ever need to setup a data service where the server and the consumer are built from two different versions of Astoria, you’ll likely want to know what is expected to work and what is not.

With the release of CTP2, we have introduced a couple of new features on the server. In the table below I’ll list these features and their behavior when it comes to cross-version calls. In the table, minimum requesting DataServiceVersion means the client must send a DSV header that’s greater than or equal to this value, and the response DSV means the server will response with this version (which also means the MDSV header sent by the client must be less than or equal to this value).


Call Uri

Minimum Requesting DataServiceVersion

Response DataServiceVersion

Friendly Feeds

Any Entity With EPM mapping and KeepInContent set to false


2.0(ATOM) / 1.0(JSON)


Any Entity With EPM mapping and KeepInContent set to true



Server Driven Paging

Any EntitySets that are paged and the number of requested entities are greater than the page size

1.0 (First page) / 2.0 (Subsequent pages with $skipToken)



Any EntitySets that are paged and the number of requested entities are less than the page size



Row Count









Accessing media links







The rule of thumb here is we require the requesting DSV to be 2.0 for all new URI constructs ($inlinecount, $count, $skipToken, $select), and the response DSV will be 2.0 if the content is incompatible with V1 response. For example, for Server Driven Paging, when the server truncates the result set, we will bump the response DSV to 2.0, because V1.0 client will ignore the continuation token and thus unable to receive the full results.

The Max Protocol Version configuration

For folks out there wanting to use V2 service and want their service to be V1 protocol compliant, you can "turn off" the features that may require a DSV of 2.0 by setting the MaxProtocolVersion configuration*. This setting is available only during service initialization:

public static void InitializeService(DataServiceConfiguration config)
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
    config.DataServiceBehavior.MaxProtocolVersion =

You can think of this as the service-side enforced "MaxDataServiceVersion" header. When this is set, any request that requires a DSV greater than 1.0 will fail even if the proper headers are present. The error message you get in this case is "The response requires that version 2 of the protocol be used, but the MaxProtocolVersion of the data service is set to DataServiceProtocolVersion.V1", and the status code of the reply is BadRequest(400).

*NOTE: We have decided to ship V2 with MaxProtocolVersion default to V1, for safety and compatibility reasons. You MUST explicitly set this to V2 in order to use any of the V2 features.

Comments (3)

  1. Greg says:

    Thanks for this post. Couple of things which might help people:

    1) Moving from CTP 1 code: the InitializeService code I had in my CTP 1 project had a IDataServiceConfiguration parameter, not a DataServiceConfiguration parameter. The DataServiceBehavior property is not present on this interface. Changed the parameter to DataServiceConfiguration and it worked fine.

    2) The Enum for MaxProtocolVersion (System.Data.Services.Common.DataServiceProtocolVersion) seems to be in the client side dll, not the server side, which means bringing in a reference to the client dll into the server project, which feels….wrong. It works though.

    3) I had to explicitly set the version to V2 to be able to use the $Count from a client app – does it default to V1?



  2. Peter Qian says:

    Good feedbacks, for #2, we have already taken a bunch of dependency of the client dll on the server side – this is fine. I’ve updated the blog for #3 – thanks for catching that 🙂

  3. Greg says:

    No problem. The technology is great!