I'm returning an ODataResult from the new Web API OData package as follows:
public ODataResult<Product> Get(ODataQueryOptions options)
{
var results = (options.ApplyTo(_db.Products) as IQueryable<Product>);
var count = results.Count;
var limitedResults = results.Take(100).ToArray();
return new ODataResult<Product>(results,null,count);
}
The above works great but it always returns an Atom response regardless of the query type. How can I return JSON?
I can see that Atom is the first supported media type within the ODataMediaTypeFormatter collection. I'd be happy just completely removing Atom support as I don't need it. Even better would be to have the content type correctly negotiated.
Have you tried setting the accept header, like this:
Accept=application/json;odata=verbose.
That should return JSON.
The OData protocol has supported JSON for a while but in V3 of the protocol application/json is mapped to something called JSON light (which is not yet implemented). So to until JSON light is supported to get JSON you have to be a little more specific, and request the more verbose version of JSON that has been in OData since V1.
I am currently also experimenting with OData support using the Beta Package you linked. We should keep in mind that it is a beta package and things might change until release. I have hit the same issue. Right now, it seems Microsoft is planning to provide OData v3 support in Web Api, looking at ODataMediaTypeFormatter reveals this.
In OData v3, there will be three formats:
- Atom (
application/atom+xml
)
- JSON Verbose (
application/json;odata=verbose
)
- JSON Light (
application/json;odata=light
)
Atom is the only and thereby default XML format of OData. The default JSON Format in OData v3 is JSON light. The old OData v2 JSON Format is what has become JSON Verbose in OData v3.
This is supported by the Spec (v20120705) section 2.2.5.1 which lists Accept and corresponding Response Headers:
application/json;odata=verbose ->  application/json;odata=verbose
application/json;odata=light  -> application/json;odata=light
application/json -> For version 1.0 and version 2.0 responses: application/json;odata=verbose. For version 3.0 responses: application/json;odata=light
Unfortunately, they haven't specified JSON light yet (section 2.2.5.1.3, emphasis mine):
The JSON light format is a new format, defined only in the OData 3.0
protocol, that optimizes for small size by not including metadata
information in the representations. The verbose format represents the
existing JSON-based format, defined by the OData 1.0, 2.0 and 3.0
protocol, that includes metadata information along with the
representation of an instance. The format for the JSON light
content-type is not defined by this version of document.
I do expect however that the JSON Light format will be a proper subset of the JSON Verbose format. The current implementation of ODataMediaTypeFormatter will only respond to application/json;odata=verbose
and application/atom+xml
headers or fallback to ATOM. Interestingly enough, it seems specifying $format=json
returns a 406.
If you want an interim solution that assumes the light format will be a proper subset of the verbose format, you can instruct the MediaTypeFormatter to respond to application/json
requests, making it a lot easier to work with OData from jQuery because we can ommit specifying the accept header:
ODataMediaTypeFormatter odataFormatter = new ODataMediaTypeFormatter(model);
odataFormatter.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));