Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsonschema 如何在单个JSON模式上验证输入和输出(具有只读的边缘案例)_Jsonschema - Fatal编程技术网

Jsonschema 如何在单个JSON模式上验证输入和输出(具有只读的边缘案例)

Jsonschema 如何在单个JSON模式上验证输入和输出(具有只读的边缘案例),jsonschema,Jsonschema,我的问题有些重叠,但差异很大,我觉得有必要提出一个新问题 我试图理解设计一个模式的最佳方法,该模式可用于在单个资源表示上验证输入和输出。这里有一个例子 { "type": "object", "properties": { "id": { "type": "number", "readOnly": true }, "title": { "type": "stri

我的问题有些重叠,但差异很大,我觉得有必要提出一个新问题

我试图理解设计一个模式的最佳方法,该模式可用于在单个资源表示上验证输入和输出。这里有一个例子

{
    "type": "object",
    "properties": {
        "id": {
            "type": "number",
            "readOnly": true
        },
        "title": {
            "type": "string"
        },
        "post": {
            "type": "string"
        }
    },
    "required": ["id", "title", "post"],
    "additionalProperties": false
};
问题是,在验证输出时,我们需要
id
title
post
必需。验证输入时,不需要一个或多个字段,如果它们提供
id
,我希望验证失败(由于
只读
关键字)

我认为正确的方法是将
required
与or结合起来,但我不确定如何将它们结合在一起

这是正确的道路,还是有更好的解决方案?有没有人有一个使用最新版本的JSON模式的例子(现在是草案7)


谢谢

这里有几种可能的方法

首先,
readOnly
不会导致JSON模式的验证过程失败。它不是一个断言,只是一个注释,应用程序可以使用它来执行操作。因此,您的服务器应用程序可以按照自己的意愿处理该问题—如果有人试图更改它,则会引发错误,或者只是默默地忽略新值

或者查看HTTP
preference
标题,如果存在
handling=lenient
,则忽略任何更改只读值的尝试,但如果存在
handling=strict
,则任何尝试都会出错

或者以不同的方式处理不同的字段。如果您有一个
lastModified
字段并支持HTTP GET=>modify=>HTTP PUT工作流,那么当您放回一个表示时,
lastModified
将不可避免地出错,但在某一点上是只读的。您不希望为过期的自动生成的时间戳中断PUT。但是,如果有人认为他们可以更改
id
字段,您可能确实希望引发错误

有鉴于此,有两种通用方法:编写一个双向工作的模式,并在应用程序层中执行额外的检查,或者分别确定输入和输出的所有内容

“双向工作”方法将从
必需的
中删除
id
,但文档一旦创建,资源将始终具有
id
。但这样一来,在创建或编写时就可以省略它,而不会出现问题。要确定这是否合理,请考虑客户端输出验证的用例。客户机是否真的需要JSON模式来检查服务器是否发送了
id
,或者客户机是否可以根据文档合理地假设服务器将正确执行此操作

对于“锁定每一个方向”的方法,您可以这样做:

{
    "definitions": {
        "common": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "number",
                    "readOnly": true
                },
                "title": {
                    "type": "string"
                },
                "post": {
                    "type": "string"
                }
            },
            "required": ["title", "post"],
            "additionalProperties": false
        },
        "input": {
            "allOf": [
                {"$ref": "#/definitions/common"},
                {"properties": {"id": false}}
            ]
        },
        "output": {
            "allOf": [
                {"$ref": "#/definitions/common"},
                {"required": ["id"]}
            ]
        }
    }
}
您需要在公共模式中定义
id
,以便
“additionalProperties”:false
了解它(我尽量避免
“additionalProperties”:false
,因为它使以兼容的方式演化表示变得困难,但如果您想使用它,这就是如何使它工作的方法)

对于输出,只需设置
id
required即可

对于输入,使用
{“属性”:{“id”:false}
禁止
id
。即使它是在“common”中定义的,
false
布尔模式总是会导致
id
在输入时验证失败

当然,您必须弄清楚应用程序如何知道要使用哪个模式,因为
readOnly
本身不会导致验证失败。这就是为什么我更喜欢读写都有一个模式,让应用程序处理差异(并记录这种处理是如何工作的)