使用 Schema 验证无效的 json 数据不会因反序列化而失败
Posted
技术标签:
【中文标题】使用 Schema 验证无效的 json 数据不会因反序列化而失败【英文标题】:Validation of an invalid json data with Schema not failing with Deserialization 【发布时间】:2020-03-11 07:19:39 【问题描述】:我正在解析以下 JSON:
"names":"organizationNames":["name":"apple"]
进入 C# 代码中定义的架构,如下所示。
public class QueryJson
#region Properties
[JsonProperty("organization")]
public HeOrganization Organization get; set;
[JsonProperty("names")]
public HeName Names get; set;
[JsonProperty("emails")]
public List<HeEmailAddress> Emails get; set;
#endregion
#region Linked Classes
public class HeOrganization
[JsonProperty("id")]
public Guid? ID get; set;
public class HeName
[JsonProperty("organizationNames")]
[Required(ErrorMessage = "Organization Name is Missing")]
public List<HeOrganizationName> OrganizationName get; set;
public class HeOrganizationName
[JsonProperty("name")]
[Required(ErrorMessage = "Name is Missing")]
public string Name get; set;
public class HeEmailAddress
[JsonProperty("address")]
[Required]
[EmailAddress]
public string Address get; set;
#endregion
如果我要传递一个明显无效的 JSON:
"names":"organizationNames":["user":"apple"]
我期待 DeserializeObject() 失败或抛出错误,但它只是将“名称”分配给 null。
var myJson = JsonConvert.DeserializeObject<T>(jsonFilter);
其中 T 是类的实例。
关于如何执行此类验证的任何建议?
【问题讨论】:
你试过了吗:newtonsoft.com/jsonschema T是什么类型的?它必须是 QueryJson 类类型 例如:var myJson = JsonConvert.DeserializeObjectRequiredAttribute
,它支持[JsonProperty(Required = Required.Always)]
。见:Using Required and JsonRequired in ASP.NET Core Model Binding with JSON body。这是否回答了您的问题,或者您是否需要一种解决方法来使 Json.NET 尊重 [RequiredAttribute]
以进行独立序列化?
【参考方案1】:
您可以使用Newtonsoft.Json.Schema 来验证任何给定 Json 的架构。
例如,对于您定义的类结构,可以生成一个等效的 Schema
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(QueryJson));
生成的Schema如下
"definitions":
"HeEmailAddress":
"type": [
"object",
"null"
],
"properties":
"address":
"type": "string",
"format": "email"
,
"required": [
"address"
]
,
"HeName":
"type": [
"object",
"null"
],
"properties":
"organizationNames":
"type": "array",
"items":
"$ref": "#/definitions/HeOrganizationName"
,
"required": [
"organizationNames"
]
,
"HeOrganization":
"type": [
"object",
"null"
],
"properties":
"id":
"type": [
"string",
"null"
]
,
"required": [
"id"
]
,
"HeOrganizationName":
"type": [
"object",
"null"
],
"properties":
"name":
"type": "string"
,
"required": [
"name"
]
,
"type": "object",
"properties":
"organization":
"$ref": "#/definitions/HeOrganization"
,
"names":
"$ref": "#/definitions/HeName"
,
"emails":
"type": [
"array",
"null"
],
"items":
"$ref": "#/definitions/HeEmailAddress"
,
"required": [
"organization",
"names",
"emails"
]
您现在可以使用 Schema 来验证您的 json。例如,对于 OP 中提供的示例无效 json
var invalidJson = @"""names"":""organizationNames"":[""user"":""apple""]";
var jsonInstance = JObject.Parse(invalidJson);
bool valid = jsonInstance.IsValid(schema); // False
【讨论】:
这很有帮助,谢谢!但我有一个后续问题 - 为什么按要求生成属性组织、名称和电子邮件?如果我不希望它被要求怎么办? 这可能有用github.com/JamesNK/Newtonsoft.Json.Schema/issues/9以上是关于使用 Schema 验证无效的 json 数据不会因反序列化而失败的主要内容,如果未能解决你的问题,请参考以下文章