使用日期字段的JSON模式验证

时间:2015-08-26 04:44:21

标签: c# json json.net schema jsonschema

我在使用Newtonsoft.Json.Schema库中的JSchemaValidatingReader时遇到了问题。问题在于验证JSON数据中的日期字段。

鉴于此架构和数据

var schemaString = "{\"type\":\"object\",\"properties\":{\"DueDate\":{\"required\":true,\"type\":\"string\",\"format\":\"date\"},\"DateCompleted\":{\"required\":true,\"type\":\"string\",\"format\":\"date-time\"}}}";
var jsonData = "{\"DueDate\":\"2015-08-25\",\"DateCompleted\":\"2015-08-27T22:40:09.3749084-05:00\"}";

我可以使用JToken.IsValid()方法正确验证数据。像这样:

IList<string> errors = new List<string>();
var schema = JSchema.Parse(schemaString);
var json = JToken.Parse(jsonData);
var isValid = json.IsValid(schema, out errors); //isValid = true with no errors

但是,如果我尝试使用JSchemaValidatingReader完成相同的操作,我会得到不同的结果。

var jsonReader = new JsonTextReader(new StringReader(jsonData));
var validatingReader = new JSchemaValidatingReader(jsonReader);
validatingReader.Schema = schema;
validatingReader.ValidationEventHandler += (o, a) => errors.Add(a.Path + ": " + a.Message);

var serializer = new JsonSerializer();
var hw = serializer.Deserialize<Homework>(validatingReader);

这将导致错误列表中包含错误消息:

  

DueDate:String&#39; 2015-08-25T00:00:00&#39;不会对格式&#39;日期&#39;进行验证。 Path&#39; DueDate&#39;,第1行,第23位。

不知何故,时间组件被添加到日期字符串中。通过设置JsonTextReader.DateFormatString属性可以避免此错误:

jsonReader.DateFormatString = "yyyy-MM-dd";

但是,这只会导致日期时间字段无法使用此错误进行验证:

  

DateCompleted:String&#39; 2015-08-27&#39;不会对格式&#39;日期时间&#39;进行验证。 Path&#39; DateCompleted&#39;,第1行,第75位。

我做错了吗?或者JSchemaValidatingReader实现是否存在问题?

2 个答案:

答案 0 :(得分:1)

问题是由JsonTextReader +解串器将日期字符串解析为DateTimes引起的。一旦发生这种情况,原始字符串就会丢失,并且验证读者必须先将DateTime转换回字符串才能进行验证。 IsValid不会发生这种情况,因为它将所有内容都读为字符串。

目前有两种解决方案:

  1. 坚持使用IsValid验证。
  2. JsonTextReader上设置DateParseHandling为DateParseHandling.None。日期将始终作为字符串读取,序列化程序将处理将它们转换为DateTime

答案 1 :(得分:0)

我认为,这是因为您有两种不同的日期格式,JSchemaValidatingReader只能处理您在jsonReader.DateFormatString中提供的格式