C# 개체를 JSON 형식으로 직렬화하려고하지만 개체가 스키마에 따라 유효하지 않은 경우 직렬화를 피하려고합니다. JSON.NET 및 Json.NET 스키마를 사용하여이 작업을 어떻게 진행해야합니까? 내가 본 것으로부터 JSON 스키마에 대한 C# 개체의 유효성 검사를 허용하는 JSON.NET 라이브러리에는 메서드가 없습니다. C# 개체를 인코딩하지 않고 유효성을 검사하는 직접적인 메서드가 없다는 것은 이상한 것처럼 보입니다. 이 방법을 사용할 수없는 이유를 알고 있습니까?직렬화 전에 스키마에 대해 개체 유효성 검사
1
A
답변
3
그것은이 API는 현재 사용할 수없는 것 같다. JSON 값을 재귀 적으로 생성하여 유효성을 검사하기 때문에 대부분의 객체 직렬화 작업이 필요하기 때문일 수 있습니다. 아니면 Newtonsoft에 아무도 없기 때문일 수도 있습니다. ever designed, specified, implemented, tested, documented and shipped that feature.
원하는 경우 file an enhancement request은 SchemaExtensions
class의 일부로이 API를 요청할 수 있습니다. 한편
NullJsonWriter
을 잡아
JSchemaValidatingWriter
및 테스트에 포장 할 수 그것의 완전한 직렬화를 생성하지 않고 POCO을 테스트-확인해야하는 경우 -
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.
0
당신은 JSON 문자열에서, 당신은 객체와 처음으로 비교하는 스키마를 필요로 할 수 없다 ..
public void Validate()
{
//...
JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}");
JToken stringToken = JToken.FromObject("pie");
stringToken.Validate(schema);
이 사진을 보셨습니까? https://www.newtonsoft.com/json/help/html/JsonSchema.htm –
[자동 생성 된 개체 참조] (https://stackoverflow.com/a/30650904/3744182)에서'NullJsonWriter'를 가져올 수 있습니다. 'JSchemaValidatingWriter'에 랩핑하고 [* JSchemaValidatingWriter *로 JSON 확인] (https://www.newtonsoft.com/jsonschema/help/html/JsonValidatingWriterAndSerializer.htm)과 같이 객체를 테스트 직렬화하십시오. – dbc
@dbc 그것은 C# 개체를 인코딩하지 않고 유효성을 검사하는 직접적인 메서드가 없다는 다소 이상한 것처럼 보입니다. 이 방법을 사용할 수없는 이유를 알고 있습니까? –