c# - 带有日期字段的 JSON 模式验证

标签 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 '2015-08-25T00:00:00' does not validate against format 'date'. Path 'DueDate', line 1, position 23.

以某种方式将时间组件添加到日期字符串中。可以通过像这样设置 JsonTextReader.DateFormatString 属性来避免此错误:

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

但是,这只会导致日期时间字段无法验证并出现此错误:

DateCompleted: String '2015-08-27' does not validate against format 'date-time'. Path 'DateCompleted', line 1, position 75.

我做错了什么吗?还是 JSchemaValidatingReader 实现有问题?

最佳答案

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

目前有两种解决方案:

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

关于c# - 带有日期字段的 JSON 模式验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32218162/

相关文章:

c# - 为什么我不能在 C# 中引用 System.Runtime.Serialization.Json

c# - 当内部属性名称不同时反序列化 JSON

c# - 如何使用 C# 为 ListView 控件中的项目添加边框?

c# - 尝试格式化 DateTime?变量原因 "No overload for method ToString takes 1 argument error"

c# - 可滚动图片框c#.net使用双缓冲停止闪烁

C# Json.net 将嵌套的 json 反序列化为字符串

c# - 如何使用 json.net 将 C# 通用列表转换为 json?

c# - 如何将类型的默认值设置为 Nothing?

javascript - 为什么我要无限循环 for() 循环?

ruby-on-rails - 使用 Ruby on Rails 显示对象