Reputation: 8145
is it possible to get metadata of an OData service in JSON format?
When I try to use format=json
, it doesn't work. Here is what I tried:
http://odata.informea.org/services/odata.svc/$metadata/?format=json
Upvotes: 23
Views: 56612
Reputation: 1383
In 2021, possibly...
The OData 4.01 specification includes support for JSON: https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_MetadataDocumentRequest
Microsoft's OData implementation added support from the following versions:
Additionally, JSON Metadata is only supported at platform implementing .NETStardard 2.0.
[sic].
If the service you're calling supports it, you can do it in the query string...
$format=application/json
$format=json
...or using the http headers:
Accept=application/json
It it doesn't... ask the provider of the service to upgrade?
Upvotes: 0
Reputation: 20997
I wrote a simple provider to parse out some of the needed information from the metadata, Feel free to expand on it. First you'll need some simple models, to expresss the data, we'll want to convert from there ugly XML names
export class ODataEntityType
{
name: string;
properties: ODataProperty[];
}
export class ODataProperty
{
name: string;
type: ODataTypes;
isNullable: boolean;
}
//Hack Until Ionic supports TS 2.4
export class ODataTypeMap
{
"Edm.Int32" = ODataTypes.Int;
"Edm.Int64" = ODataTypes.Long;
"Edm.Decimal" = ODataTypes.Decimal;
"Edm.Double" = ODataTypes.Double;
"Edm.Guid" = ODataTypes.Guid;
"Edm.String" = ODataTypes.String;
"Edm.Boolean" = ODataTypes.Bool;
"Edm.DateTime" = ODataTypes.DateTime;
"Edm.DateTimeOffset" = ODataTypes.DateTimeOffset;
}
export enum ODataTypes
{
Int,
Long,
Decimal,
Double,
Guid,
String,
Bool,
DateTime,
DateTimeOffset
}
This is the provider:
import { Injectable } from "@angular/core";
import { Http } from "@angular/http";
import * as X2JS from 'x2js';
import * as _ from 'underscore';
import { ODataEntityType, ODataProperty, ODataTypes, ODataTypeMap } from "../models/ODataEntityType";
@Injectable()
export class ODataMetadataToJsonProvider {
x2js = new X2JS();
public entityTypeMap: Dictionary = new Dictionary();
public entityTypes : ODataEntityType[];
constructor(public http: Http) {
}
parseODataMetadata(metadataUrl: string) {
this.http.get(metadataUrl).subscribe(data => {
let metadata: any = this.x2js.xml2js(data.text());
let rawEntityTypes = _.filter(metadata.Edmx.DataServices.Schema, x => x["EntityType"] != null);
if(rawEntityTypes.length == 0)
{
return;
}
this.entityTypes = _.map(rawEntityTypes[0]["EntityType"], t => {
let oDataEntityType = new ODataEntityType();
oDataEntityType.name = t["_Name"];
oDataEntityType.properties = _.map(t["Property"], p => {
let property = new ODataProperty();
property.name = p["_Name"];
let typeStr: string = p["_Type"];
property.type = ODataTypeMap[typeStr];
property.isNullable = !!p["_Nullable"];
return property;
});
return oDataEntityType;
});
});
}
}
Upvotes: 1
Reputation: 329
You can use jQuery to get the relevant information from an OData service $metadata.
Take for example:
You write a unit test to check the OData entities property names matches with your application entities. Then you have to retrieve the properties of the OData entity.
$.ajax({
type: "GET",
url: "/destinations/odata-service/$metadata",
beforeSend: function() {
console.log("before send check");
},
dataType: "xml",
contentType: "application/atom+xml",
context: document.body,
success: function(xml) {
console.log("Success ResourceTypes");
var ODataTypeINeed = $(xml).find('EntityType').filter(function(){
return $(this).attr('Name') == 'ODataTypeINeed'
});
$(ODataTypeINeed).find('Property').each(function() {
console.log($(this).attr('Name')); //List of OData Entity properties
});
},
error: function(err) {
console.log(err);
}
});
Upvotes: 1
Reputation: 47091
As an alternative to ?$format=json
, you could also just set the following two headers :
Accept: application/json
Content-Type: application/json; charset=utf-8
I'm not sure which is the minimum Odata version required, but this works perfectly for me on Microsoft Dynamics NAV 2016, which uses Odata v4.
Upvotes: 2
Reputation: 4555
The $metadata
document is in the CSDL format, which currently only has an XML representation. (As a side note, if you do want to request the json format for a different kind of OData payload, make sure the format
query token has a $
in front of it: $format=json
.)
So, no it is not possible. You can, however, get the service document in JSON, which is a subset of the $metadata document:
http://odata.informea.org/services/odata.svc?$format=json
This won't have type information, but it will list the available entry points of the service (i.e., the entity sets).
Upvotes: 29
Reputation: 202176
I agreed with the previous answer. This isn't supported by the specification but some OData frameworks / libraries are about to implement this feature.
I think about Olingo. This is could be helpful for you if you also implement the server side. See this issue in the Olingo JIRA for more details:
Hope it helps you, Thierry
Upvotes: 1