JsonSchema.Net验证异常:值应为object实际为string问题排查
问题:JSON Schema验证始终返回false,报错“Value is 'string' but should be 'object' at #/type”
C#类定义
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; } }
生成的JSON 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" } } } }
验证函数
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,报错信息:
Value is "string" but should be "object" at #/type
曾怀疑Schema顶层type与字段type冲突,但移除字段type后错误仍存在。
解决方案
问题出在验证函数的参数传递方式:
JsonSchema.Validate()方法接收string类型参数时,不会自动将其解析为JSON对象,而是直接把这个字符串当作待验证的值。你的Schema要求顶层是object类型,但传入的是string类型的JSON文本,自然会触发“值类型不匹配”的错误——哪怕你提前用JsonDocument.Parse检查了格式,也改变不了Validate方法对参数的处理逻辑。
修正后的验证函数
将JSON字符串解析为JsonElement或JsonNode后再传入Validate方法:
方式一:使用JsonElement
static bool IsValid(string requestedAuthorizationDetails, JsonSchema authorizationDetailsSchema) { if (!JsonDocument.TryParse(requestedAuthorizationDetails, out var doc)) { return false; } var result = authorizationDetailsSchema.Validate(doc.RootElement, new ValidationOptions { OutputFormat = OutputFormat.Detailed }); Console.WriteLine($"{result.Message} at {result.SchemaLocation.Source}"); return result.IsValid; }
方式二:使用JsonNode
static bool IsValid(string requestedAuthorizationDetails, JsonSchema authorizationDetailsSchema) { JsonNode? node; try { node = JsonNode.Parse(requestedAuthorizationDetails); } catch { return false; } if (node == null) return false; var result = authorizationDetailsSchema.Validate(node, new ValidationOptions { OutputFormat = OutputFormat.Detailed }); Console.WriteLine($"{result.Message} at {result.SchemaLocation.Source}"); return result.IsValid; }
这样Validate方法会验证解析后的JSON对象,而非原始字符串,就能匹配Schema的类型要求,解决错误。
内容的提问来源于stack exchange,提问作者Szyszka947
相关产品推荐
相关产品推荐

