英文:
JsonSchema.Net stops validation at first property with inappropriate error
问题
我使用 JsonSchema.Net.Generation 生成了 JSON 模式。我的模式类如下:
class PaymentInitiationSchema
{
    [Required]
    [JsonPropertyName("type")]
    public string Type { get; set; }
    [Required]
    [JsonPropertyName("actions")]
    public string[] Actions { get; set; }
    [Required]
    [JsonPropertyName("locations")]
    public string[] Locations { get; set; }
    [Required]
    [JsonPropertyName("instructedAmount")]
    public InstructedAmount InstructedAmount { get; set; }
    [Required]
    [JsonPropertyName("creditorName")]
    public string CreditorName { get; set; }
    [Required]
    [JsonPropertyName("creditorAccount")]
    public CreditorAccount CreditorAccount { get; set; }
    [Required]
    [JsonPropertyName("reemitanceInformationUnstructured")]
    public string ReemitanceInformationUnstructured { get; set; }
}
class InstructedAmount
{
    [Required]
    [JsonPropertyName("currency")]
    public string Currency { get; set; }
    [Required]
    [JsonPropertyName("amount")]
    public decimal Amount { get; set; }
}
class CreditorAccount
{
    [Required]
    [JsonPropertyName("iban")]
    public string Iban { get; set; }
}
生成的模式如下:
{
   "type":"object",
   "properties":{
      "type":{
         "type":"string"
      },
      "actions":{
         "$ref":"#/$defs/array"
      },
      "locations":{
         "$ref":"#/$defs/array"
      },
      "instructedAmount":{
         "type":"object",
         "properties":{
            "currency":{
               "type":"string"
            },
            "amount":{
               "type":"number"
            }
         },
         "required":[
            "currency",
            "amount"
         ]
      },
      "creditorName":{
         "type":"string"
      },
      "creditorAccount":{
         "type":"object",
         "properties":{
            "iban":{
               "type":"string"
            }
         },
         "required":[
            "iban"
         ]
      },
      "reemitanceInformationUnstructured":{
         "type":"string"
      }
   },
   "required":[
      "type",
      "actions",
      "locations",
      "instructedAmount",
      "creditorName",
      "creditorAccount",
      "reemitanceInformationUnstructured"
   ],
   "$defs":{
      "array":{
         "type":"array",
         "items":{
            "type":"string"
         }
      }
   }
}
我创建了一个验证给定 JSON 的示例函数:
static bool IsValid(string requestedAuthorizationDetails, JsonSchema authorizationDetailsSchema)
{
    try
    {
        JsonDocument.Parse(requestedAuthorizationDetails);
    }
    catch
    {
        return false;
    }
    var result = authorizationDetailsSchema.Validate(requestedAuthorizationDetails, new ValidationOptions
    {
        OutputFormat = OutputFormat.Detailed
    });
    Console.WriteLine(result.Message + " at " + result.SchemaLocation.Source);
    return result.IsValid;
}
但是对于这个调用,它总是返回 false:
var schemaBuilder = new JsonSchemaBuilder();
var schema = schemaBuilder.FromType<PaymentInitiationSchema>().Build();
Console.WriteLine(IsValid(@"
{
  ""type"": ""payment_initiation"",
  ""actions"": [
    ""initiate"",
    ""status"",
    ""cancel""
  ],
  ""locations"": [
    ""https://example.com/payments""
  ],
  ""instructedAmount"": {
    ""currency"": ""EUR"",
    ""amount"": 123.50
  },
  ""creditorName"": ""Merchant A"",
  ""creditorAccount"": {
    ""iban"": ""DE02100100109307118603""
  },
  ""remittanceInformationUnstructured"": ""Ref Number Merchant""
}", schema));
而且错误总是相同的:
Value is "string" but should be "object" at #/type
真的不明白为什么。我想也许在 JSON 模式的顶部和作为必需参数的 type 之间存在冲突。但即使我从参数中移除了 type,仍然出现相同的错误。
有什么问题吗?
英文:
I have JSON schema generated using JsonSchema.Net.Generation. My classes for schema are as below:
class PaymentInitiationSchema
{
    [Required]
    [JsonPropertyName("type")]
    public string Type { get; set; }
    [Required]
    [JsonPropertyName("actions")]
    public string[] Actions { get; set; }
    [Required]
    [JsonPropertyName("locations")]
    public string[] Locations { get; set; }
    [Required]
    [JsonPropertyName("instructedAmount")]
    public InstructedAmount InstructedAmount { get; set; }
    [Required]
    [JsonPropertyName("creditorName")]
    public string CreditorName { get; set; }
    [Required]
    [JsonPropertyName("creditorAccount")]
    public CreditorAccount CreditorAccount { get; set; }
    [Required]
    [JsonPropertyName("reemitanceInformationUnstructured")]
    public string ReemitanceInformationUnstructured { get; set; }
}
class InstructedAmount
{
    [Required]
    [JsonPropertyName("currency")]
    public string Currency { get; set; }
    [Required]
    [JsonPropertyName("amount")]
    public decimal Amount { get; set; }
}
class CreditorAccount
{
    [Required]
    [JsonPropertyName("iban")]
    public string Iban { get; set; }
}
and it's the generated schema:
{
   "type":"object",
   "properties":{
      "type":{
         "type":"string"
      },
      "actions":{
         "$ref":"#/$defs/array"
      },
      "locations":{
         "$ref":"#/$defs/array"
      },
      "instructedAmount":{
         "type":"object",
         "properties":{
            "currency":{
               "type":"string"
            },
            "amount":{
               "type":"number"
            }
         },
         "required":[
            "currency",
            "amount"
         ]
      },
      "creditorName":{
         "type":"string"
      },
      "creditorAccount":{
         "type":"object",
         "properties":{
            "iban":{
               "type":"string"
            }
         },
         "required":[
            "iban"
         ]
      },
      "reemitanceInformationUnstructured":{
         "type":"string"
      }
   },
   "required":[
      "type",
      "actions",
      "locations",
      "instructedAmount",
      "creditorName",
      "creditorAccount",
      "reemitanceInformationUnstructured"
   ],
   "$defs":{
      "array":{
         "type":"array",
         "items":{
            "type":"string"
         }
      }
   }
}
I created sample function to validate given JSON:
static bool IsValid(string requestedAuthorizationDetails, JsonSchema authorizationDetailsSchema)
{
    try
    {
        JsonDocument.Parse(requestedAuthorizationDetails);
    }
    catch
    {
        return false;
    }
    var result = authorizationDetailsSchema.Validate(requestedAuthorizationDetails, new ValidationOptions
    {
        OutputFormat = OutputFormat.Detailed
    });
    Console.WriteLine(result.Message + " at " + result.SchemaLocation.Source);
    return result.IsValid;
}
And it's always false for this call:
var schemaBuilder = new JsonSchemaBuilder();
var schema = schemaBuilder.FromType<PaymentInitiationSchema>().Build();
Console.WriteLine(IsValid(@"{
      ""type"": ""payment_initiation"",
      ""actions"": [
         ""initiate"",
         ""status"",
         ""cancel""
      ],
      ""locations"": [
         ""https://example.com/payments""
      ],
      ""instructedAmount"": {
         ""currency"": ""EUR"",
         ""amount"": 123.50
      },
      ""creditorName"": ""Merchant A"",
      ""creditorAccount"": {
         ""iban"": ""DE02100100109307118603""
      },
      ""remittanceInformationUnstructured"": ""Ref Number Merchant""
   }", schema));
And the error is also always the same:
> Value is "string" but should be "object" at #/type
Really don't understand why. I thought that maybe there is conflict between type at top of the JSON scheme and the type as required parameter. But even if I removed type from parameters the same error stills occurs.
What's wrong with it?
答案1
得分: 1
请注意,以下是您提供的文本的翻译:
"I'm not sure what version of the libs you're using, but have you checked over at https://json-everything.net?
Inputting your generated schema and the instance you wrote, it says that two properties are the problems (I've edited the output down to just the errors for ease of viewing):
{
  "valid": false,
  "evaluationPath": "",
  "schemaLocation": "https://json-everything.net/43e8b7754c",
  "instanceLocation": "",
  "errors": {
    "required": "Required properties [\"reemitanceInformationUnstructured\"] were not present"
  },
  "details": [
    {
      "valid": false,
      "evaluationPath": "/properties/creditorAccount",
      "schemaLocation": "https://json-everything.net/43e8b7754c#/properties/creditorAccount",
      "instanceLocation": "/creditorAccount",
      "errors": {
        "required": "Required properties [\"iban\"] were not present"
      }
    }
  ]
}
It looks like you have two typos. Changing remittanceInformationUnstructured to reemitanceInformationUnstructured and ban to iban allows the data to validate."
英文:
I'm not sure what version of the libs you're using, but have you checked over at https://json-everything.net?
Inputting your generated schema and the instance you wrote, it says that two properties are the problems (I've edited the output down to just the errors for ease of viewing):
{
  "valid": false,
  "evaluationPath": "",
  "schemaLocation": "https://json-everything.net/43e8b7754c",
  "instanceLocation": "",
  "errors": {
    "required": "Required properties [\"reemitanceInformationUnstructured\"] were not present"
  },
  "details": [
    {
      "valid": false,
      "evaluationPath": "/properties/creditorAccount",
      "schemaLocation": "https://json-everything.net/43e8b7754c#/properties/creditorAccount",
      "instanceLocation": "/creditorAccount",
      "errors": {
        "required": "Required properties [\"iban\"] were not present"
      }
    }
  ]
}
It looks like you have two typos.  Changing remittanceInformationUnstructured to reemitanceInformationUnstructured and ban to iban allows the data to validate.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论