目前看来此 API 不可用。猜测一下,这可能是因为递归生成要验证的 JSON 值涉及序列化对象的大部分工作。或者可能只是因为 Newtonsoft ever designed, specified, implemented, tested, documented and shipped that feature 没有人。
如果您愿意,您可以 file an enhancement request 请求此 API,可能作为 SchemaExtensions class 的一部分。
与此同时,如果您确实需要测试验证 POCO 而不生成它的完整序列化(因为例如结果会非常大),您可以从 Reference to automatically created objects 中获取 NullJsonWriter,将其包装在JSchemaValidatingWriter 并测试序列化您的对象,如 Validate JSON with JSchemaValidatingWriter 所示。 NullJsonWriter 实际上并没有写任何东西,因此使用它可以消除生成完整序列化(作为 string 或 JToken)的性能和内存开销。
首先,添加如下静态方法:
public static class JsonExtensions
{
public static bool TestValidate<T>(T obj, JSchema schema, SchemaValidationEventHandler handler = null, JsonSerializerSettings settings = null)
{
using (var writer = new NullJsonWriter())
using (var validatingWriter = new JSchemaValidatingWriter(writer) { Schema = schema })
{
int count = 0;
if (handler != null)
validatingWriter.ValidationEventHandler += handler;
validatingWriter.ValidationEventHandler += (o, a) => count++;
JsonSerializer.CreateDefault(settings).Serialize(validatingWriter, obj);
return count == 0;
}
}
}
// Used to enable Json.NET to traverse an object hierarchy without actually writing any data.
class NullJsonWriter : JsonWriter
{
public NullJsonWriter()
: base()
{
}
public override void Flush()
{
// Do nothing.
}
}
然后像这样使用它:
// Example adapted from
// https://www.newtonsoft.com/jsonschema/help/html/JsonValidatingWriterAndSerializer.htm
// by James Newton-King
string schemaJson = @"{
'description': 'A person',
'type': 'object',
'properties': {
'name': {'type':'string'},
'hobbies': {
'type': 'array',
'maxItems': 3,
'items': {'type':'string'}
}
}
}";
var schema = JSchema.Parse(schemaJson);
var person = new
{
Name = "James",
Hobbies = new [] { ".Net", "Blogging", "Reading", "XBox", "LOLCATS" },
};
var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var isValid = JsonExtensions.TestValidate(person, schema, (o, a) => Console.WriteLine(a.Message), settings);
// Prints Array item count 5 exceeds maximum count of 3. Path 'hobbies'.
Console.WriteLine("isValid = {0}", isValid);
// Prints isValid = False
顺便提防案件。 Json.NET 架构为 case sensitive,因此您需要在测试验证时使用适当的合约解析器。
示例fiddle。