Get the OData catalog for Web API OData v4 in XML
Asked Answered
H

2

6

I am trying to get a Web API OData V4 endpoint up and running.

I got it going finally (after removing all the DateTime properties from my endpoint) and now the listing of the entities is in JSON.

I love JSON, but I use LinqPad to test my endpoints. It does not understand the JSON for the listing of the entities that are in my feed.

I have looked and can't seem to find a way to change this back to XML, so I am asking here.

Is there a way to have the listing of entities for a Web API OData v4 feed be in XML rather than JSON?

Heliotrope answered 8/8, 2014 at 19:11 Comment(1)
In the current V4 library $metadata is only supported in XML format, queries are only supported in JSON (Content-Type/Accept header or $format=.. query param is used to determine requested type). HTTP header name for OData version request/response has changed between V3/V4 (hence BreezeJs/DataJS not working). Cors support in Asp.Net/MVC/API/OData is scattered and doesn't work well together.Mikiso
S
14

Sorry to post another answer, but my first one was getting too lengthy. I found this link: V4 always returns Json and sure enough, the very last suggestion does work:

In WebAPiConfig, add namespace references to:

using System.Net.Http.Formatting;
using System.Web.OData.Formatter;

and then add something like:

var formatters = ODataMediaTypeFormatters.Create();
config.Formatters.InsertRange(0, formatters);

The entity listing now gets returned as xml.

The downside, is now all the responses default to the less preferred, verbose xml/atom.

The upside, is that the $format request is now honored in v4. So to get back to json, you can issue the url (without messing with headers) as: http://<myodataurl>?$format=application/json;odata.metadata=full (or minimal or none)

However, as stated previous, LinqPad still does not recognize the v4 schema, and will not connect correctly to this endpoint.

Selaginella answered 12/8, 2014 at 16:14 Comment(1)
Be aware that: In XML format you get a different structure back than in JSON. This is because different models are serialized. The XML version is serialized by writing out the EdmModel to an EdmSchema (done by the OData delegating handler). The Json version is the serialized content of the EdmModel (done by the MVC handler). By mixing the formatters which are resolved as (Array[0 to length-1]), the first formatter who says it can write the type will win. For XML?/$metadata it's the OData formatter, for JSON?/$metadata it's the MVC formatter.Mikiso
S
2

If you have setup a Web API service using the basic, default configurations that the MS walkthroughs suggest, then the response formatter is already configured and will use json by default, or xml if so prompted.

So the prompt for an xml response usually comes from the client request. At its basic form, the request will contain a Accept: application/atom+xml,application/xml header. If it does not, I believe the Web API response will default to json.

For your particular question, there is an alternative for LinqPad. When you setup your OData connection, the dialog has a Formatter option of Xml or Json, which tells Linqpad to issue the corresponding Accept header in its request.

Using Fiddler to monitor the traffic, if you set the LinqPad OData connection to use the xml formatter, the request contains the headers:

MaxDataServiceVersion: 3.0;NetFx
Accept: application/atom+xml,application/xml

and the response comes back as an atom/xml feed.

If you set the option to use the json formatter, the request contains the headers:

MaxDataServiceVersion: 3.0;NetFx
Accept: application/json;odata=minimalmetadata

and the response comes back as json.

For oData v3, LinqPad handles both just fine.

Edit

This now sounds vaguely familiar with some test I ran a short time ago...I'm not sure if LinqPad supports the v4 protocol yet. It uses WCF Data Services client under the covers, and those libraries stopped at OData v3. And, in fact, as you see from the headers above, the request will only talk to a v3 service.

So your issue is not that the Web Api is not supporting both xml and json. The issue is that LinqPad does not yet connect to a v4 oData service. Using Fiddler or other similar tool, you should be able to request both json and/or xml from the service.

Selaginella answered 8/8, 2014 at 20:41 Comment(4)
btw...Visual Studio Lightswitch, which uses OData as its service infrastructure, won't talk to v4 either...Selaginella
This does not work for the catalog (the listing of what entities are available)Heliotrope
The <url>/$metadata request comes back as xml for V3 no matter what. If you are saying it defaults as json for V4 (json is now the recommended format), then perhaps you are right - there is no way to force it to return xml. But again, the main issue is that the response will include its version, and if a V3 client such as LinqPad sees V4, it won't really matter if the response is json or xml...it will simply ignore the response altogether.Selaginella
Just verified your claim. No matter what the Accept header is (Accept: application/atom+xml,application/xml;q=0.8) the response for the entity listing comes back with: Content-Type: application/json; odata.metadata=minimal; odata.streaming=true and OData-Version: 4.0.Selaginella

© 2022 - 2024 — McMap. All rights reserved.