问题
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
回答1:
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).
回答2:
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:
- OLINGO-570 - https://issues.apache.org/jira/browse/OLINGO-570
Hope it helps you, Thierry
回答3:
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.
回答4:
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);
}
});
回答5:
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;
});
});
}
}
来源:https://stackoverflow.com/questions/18683338/get-odata-metadata-in-json-format