以JSON格式获取OData $metadata

23

是否可以以JSON格式获取OData服务的元数据?

当我尝试使用format=json时,它无法工作。以下是我的尝试:

http://odata.informea.org/services/odata.svc/$metadata/?format=json
6个回答

27

$metadata文档采用CSDL格式,目前仅具有XML表示形式。(顺带一提,如果您希望请求不同类型的OData有效负载的json格式,请确保查询令牌format前面有一个$$format=json。)

所以,不,这是不可能的。但是,您可以获取JSON格式的服务文档,它是$metadata文档的子集:

http://odata.informea.org/services/odata.svc?$format=json

这不会包含类型信息,但它将列出服务的可用入口点(即实体集)。


2
作为 ?$format=json 的替代方案,您也可以设置以下两个标头:
  • Accept: application/json
  • Content-Type: application/json; charset=utf-8
我不确定需要的最低 Odata 版本是什么,但这在使用 Odata v4 的 Microsoft Dynamics NAV 2016 上完美运行。

我在零售服务器元数据上尝试使用此代码,但是出现了“意外的‘v’”错误。 - Shan Khan

1
我编写了一个简单的提供程序,以从元数据中解析出一些所需信息。随意扩展它。首先,您需要一些简单的模型来表达数据,我们希望从那里转换它们丑陋的XML名称。
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
}

这是提供者:
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;
            });
        });
    }
}

1
你可以使用jQuery从OData服务$metadata中获取相关信息。
例如:
你编写一个单元测试来检查OData实体属性名称是否与应用程序实体匹配。然后你需要检索OData实体的属性。
$.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);
            }
 });

1
我同意之前的回答。虽然这不被规范支持,但一些OData框架/库即将实现此功能。
我考虑使用Olingo。如果您也实现了服务器端,这可能对您有所帮助。有关更多详细信息,请参见Olingo JIRA中的此问题:
OLINGO-570 - https://issues.apache.org/jira/browse/OLINGO-570 希望对您有所帮助, Thierry

0

可能在2021年...

OData 4.01规范包括对JSON的支持:https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_MetadataDocumentRequest

微软的OData实现从以下版本开始添加支持:

  • ODataLib 7.7.3(发布于2020年9月24日)
  • WebAPI 7.5.4(发布于2020年12月29日)

此外,JSON Metadata 仅受.NETStardard 2.0实现的平台支持。 [原文如此]

如果您调用的服务支持它,可以在查询字符串中执行:

  • $format=application/json
  • $format=json

...或使用http标头:

  • Accept=application/json

如果不支持,请要求服务提供者升级?


现在这个已经可以工作了。虽然不是在 OP 的上下文中,但是在我们使用的本地 OData 服务中(我之前做了一些更改,现在刚好碰巧看到了这个线程)。当我回头查看包管理器 UI 时,让我想知道是否手动编辑了 packages.config 将目标框架更改为“netstandard2.0”,因为我没有在 UI 中看到目标框架。总之,一旦 packages.config 对于 OData 部分具有正确的目标框架,OData 就开始将 CSDL 显示为 JSON(CSDL 作为 JSON 仅适用于针对 NetStandard 2.0 的版本的包)。 - unbob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接