5

如果在 SenseNet 设置对象中使用 JSON 数组,则无法通过 OData API 访问它们。

例如,考虑以下Root/System/Settings/Portal.settings默认安装的 SenseNet 设置对象:

{
    ClientCacheHeaders: [
        { ContentType: "PreviewImage", MaxAge: 1 },
        { Extension: "jpeg", MaxAge: 604800 },
        { Extension: "gif", MaxAge: 604800 },
        { Extension: "jpg", MaxAge: 604800 },
        { Extension: "png", MaxAge: 604800 },
        { Extension: "swf", MaxAge: 604800 },
        { Extension: "css", MaxAge: 600 },
        { Extension: "js", MaxAge: 600 }
    ],
    UploadFileExtensions: {
        "jpg": "Image",
        "jpeg": "Image",
        "gif": "Image",
        "png": "Image",
        "bmp": "Image",
        "svg": "Image",
        "svgz": "Image",
        "tif": "Image",
        "tiff": "Image",
        "xaml": "WorkflowDefinition",
        "DefaultContentType": "File"
    },
    BinaryHandlerClientCacheMaxAge: 600,
    PermittedAppsWithoutOpenPermission: "Details"
}

通过 OData API 查看此对象时,不包括 ClientCacheHeaders 字段:

{
    "d": {
        "UploadFileExtensions.jpg": "Image",
        "UploadFileExtensions.jpeg": "Image",
        "UploadFileExtensions.gif": "Image",
        "UploadFileExtensions.png": "Image",
        "UploadFileExtensions.bmp": "Image",
        "UploadFileExtensions.svg": "Image",
        "UploadFileExtensions.svgz": "Image",
        "UploadFileExtensions.tif": "Image",
        "UploadFileExtensions.tiff": "Image",
        "UploadFileExtensions.xaml": "WorkflowDefinition",
        "UploadFileExtensions.DefaultContentType": "File",
        "BinaryHandlerClientCacheMaxAge": 600,
        "PermittedAppsWithoutOpenPermission": "Details",
    }
}

如果您使用以下查询专门搜索 ClientCacheHeaders 字段:

Odata.svc/Root/System/Settings('Portal.settings')?&metadata=no&$select=ClientCacheHeaders

API 返回空值:

{
    "d": {
        "ClientCacheHeaders": null
    }
}

我知道设置文件中允许使用 JSON 数组,因为上面的示例在描述设置使用的SenseNet wiki 页面中被引用。

我是否错误地执行了我的 OData 查询,或者这是 SenseNet API 中的某种解析错误?

4

2 回答 2

3

这是 Miklos 建议的自定义 OData 函数的实现。完成此操作后,您必须按照此处所述注册 OData 调用。

public static class OData
{
    [ODataFunction]
    public static string GetMySettings(Content content)
    {
        var retstr = "";
        try
        {
            var settingsFile = Settings.GetSettingsByName<Settings>("MySettings", content.Path);
            var node = Node.LoadNode(settingsFile.Path) as Settings;
            var bindata = node.GetBinary("Binary");

            using (var sr = bindata.GetStream())
            using (var tr = new System.IO.StreamReader(sr))
                retstr = tr.ReadToEnd();
        }
        catch (Exception e)
        {
            SnLog.WriteException(e);
        }

        return retstr; 
    }
}
于 2017-09-07T17:06:11.620 回答
2

这是odata api 后面的当前动态 json 字段转换的一个限制。它实际上将这些设置 json 属性转换为sensenet 字段,因此您在 odata 响应中看到的不是实际设置 json,而只是可以转换为 sensenet 字段的片段(好奇:它发生在JsonDynamicFieldHelperBuildDynamicFieldMetadata方法)。

不幸的是,sensenet 中没有用于处理 json 数组的内置字段类型,无法将 json 数组转换为字段值,这就是系统跳过它的原因。

解决方法 1

分两步在 javascript 中获取原始设置 json 。以下请求为您提供二进制字段的直接 url:

/odata.svc/Root/System/Settings('Portal.settings')?&metadata=no&$select=Binary

......像这样的东西:

/binaryhandler.ashx?nodeid=1084&propertyname=Binary&checksum=1344168

...如果您加载它,您将获得完整的原始 json,包括数组。

请注意:默认情况下,访问者无法访问设置,原因是:它们可能包含敏感信息。因此,如果您想让您的用户直接访问设置(您尝试过的方式或上面第一个解决方法中描述的方式),您必须为这些设置文件上的必要用户组授予打开权限。第二种解决方法不是这种情况。

解决方法 2

创建一个自定义 odata 操作,该操作以您选择的格式从服务器返回设置。这是一个更好的解决方案,因为这样您可以控制设置文件的哪些部分实际上可供客户端访问。

于 2017-09-05T20:31:40.780 回答