在 SenseNet 设置中使用 JSON 个数组

Using JSON arrays in SenseNet settings

如果在 SenseNet 设置对象中使用 JSON 数组,则无法通过 OData API.

访问它们

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

{
    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 returns null:

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

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

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

这是当前动态json字段转换落后于odataapi的限制。它实际上将这些设置 json 属性转换为 sensenet 字段 ,因此您在 odata 响应中看到的不是实际设置 json,而只是可以转换为 sensenet 字段(出于好奇:它发生在 JsonDynamicFieldHelper class、BuildDynamicFieldMetadata 方法中)。

而且不幸的是 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,包括数组。

Please note: Settings are not accessible to visitors by default, for a reason: they may contain sensitive information. So if you want to let your users access settings directly (the way you tried or the way described in the first workaround above), you'll have to give open permission for the necessary user groups on those setting files. This is not the case with the second workaround.

解决方法 2

创建一个 custom odata action,returns 以您从服务器选择的格式设置。这是一个更好的解决方案,因为这样您就可以控制客户端实际可以访问设置文件的哪些部分。

这是 Miklos 建议的自定义 OData 函数的实现。完成后,您必须按照 here.

所述注册 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; 
    }
}