c# - Can Json Schema Validation via Newtonsoft.Json.Schema validate VALUES? -




i have small sample. if json good, works correctly. if change "tag" (aka, property name), works correctly having invalid messages. if change value of guid non-guid-value, json schema validation not fail.

is there way fail validation guid value?

public class mycoolobject {     public guid theuuid { get; set; }      public int32 theinteger { get; set; }      public datetime thedatetime { get; set; } } 

and test method. when = 2 (and i'm setting string contain "notaguid-3333-3333-3333-333333333333"), when don't error messages like to.

    private static void runjsonschemavalidate()     {          /* note, theuuid of type "string" , format "guid" */         string jsonschematext = @"                 {                   ""typename"": ""mycoolobject"",                   ""additionalproperties"": false,                   ""type"": ""object"",                   ""required"": [                     ""theuuid"",                     ""theinteger"",                     ""thedatetime""                   ],                   ""properties"": {                     ""theuuid"": {                       ""type"": ""string"",                       ""format"": ""guid""                     },                     ""theinteger"": {                       ""type"": ""integer""                     },                     ""thedatetime"": {                       ""type"": ""string"",                       ""format"": ""date-time""                     }                   },                   ""$schema"": ""http://json-schema.org/draft-04/schema#""                 }         ";          newtonsoft.json.schema.jschema jschem = newtonsoft.json.schema.jschema.parse(jsonschematext);          (int = 0; < 3; i++)         {              string jsoncontent = string.empty;              switch (i)             {                 case 1:                     /* bad json, change property name */                     jsoncontent = @"{                         ""theuuidxxx"": ""33333333-3333-3333-3333-333333333333"",                         ""theinteger"": 2147483647,                         ""thedatetime"": ""2017-08-22t15:32:10.7023008-04:00""                     }";                     break;                 case 2:                     /* bad json, change property value */                     jsoncontent = @"{                         ""theuuid"": ""notaguid-3333-3333-3333-333333333333"",                         ""theinteger"": 2147483647,                         ""thedatetime"": ""2017-08-22t15:32:10.7023008-04:00""                     }";                     break;                 case 3:                     /* bad json, bad integer */                     jsoncontent = @"{                         ""theuuid"": ""33333333-3333-3333-3333-333333333333"",                         ""theinteger"": notanumber,                         ""thedatetime"": ""2017-08-22t15:32:10.7023008-04:00""                     }";                     break;                 case 4:                     /* bad json, bad date */                     jsoncontent = @"{                         ""theuuid"": ""33333333-3333-3333-3333-333333333333"",                         ""theinteger"": 2147483647,                         ""thedatetime"": ""notadate""                     }";                     break;                 default:                     /* json */                     jsoncontent = @"{                         ""theuuid"": ""33333333-3333-3333-3333-333333333333"",                         ""theinteger"": 2147483647,                         ""thedatetime"": ""2017-08-22t15:32:10.7023008-04:00""                     }";                     break;              }              /* start meat of procedure */              newtonsoft.json.linq.jobject jobj = newtonsoft.json.linq.jobject.parse(jsoncontent);              ilist<string> messages;             bool valid = jobj.isvalid(jschem, out messages);              /* endthe meat of procedure */               if (!valid)             {                 string errormsg = "i=" + i.tostring() + ":" + string.join(",", messages);                 console.writeline(string.empty);                 console.writeline(string.empty);                 console.writeline(errormsg);             }             else             {                 console.writeline(string.empty);                 console.writeline(string.empty);                 console.writeline("i=" + i.tostring() + ":" + "good json yes");                  mycoolobject thisshouldworkwhenvalidationpasses = newtonsoft.json.jsonconvert.deserializeobject<mycoolobject>(jsoncontent);              }              console.writeline(string.empty);             console.writeline("--------------------------------------------------");             console.writeline(string.empty);           } 

and packages

<?xml version="1.0" encoding="utf-8"?> <packages>    <package id="newtonsoft.json" version="10.0.2" targetframework="net45" />   <package id="newtonsoft.json.schema" version="3.0.3" targetframework="net45" />  </packages> 

so happening when i=2, json-schema passes, mycoolobject thisshouldworkwhenvalidationpasses throws exception....

i=2:good json yes

unhandled exception: newtonsoft.json.jsonserializationexception: error converting value "notaguid-3333-3333-3333-333333333333" type 'system.guid'. path 'theuuid', line 2, position 77. ---> system.argumentexception: not cast or convert system.string system.guid.

:(

i'm trying have json-schema fail earlier.

the end-game perform json-schema-validation without exceptions getting thrown. after "everything clear" try load objects. real stuff more complex, small demo shows issue(s).

i replaced "meat of procedure" below code

            /* start meat of procedure */              newtonsoft.json.jsontextreader reader = new newtonsoft.json.jsontextreader(new system.io.stringreader(jsoncontent));              newtonsoft.json.schema.jschemavalidatingreader validatingreader = new newtonsoft.json.schema.jschemavalidatingreader(reader);             validatingreader.schema = jschema.parse(schemajson);              ilist<string> messages = new list<string>();             validatingreader.validationeventhandler += (o, a) => messages.add(a.message);              newtonsoft.json.jsonserializer serializer = new newtonsoft.json.jsonserializer();             /* below issue code..you still try serialize object...and can throw exception */             mycoolobject p = serializer.deserialize<mycoolobject>(validatingreader);             bool valid = !messages.any();              /* end meat of procedure */ 

but again, subject exceptions being thrown .. trying validate.

thanks jeroen mostert hint led me solution:

            /* start meat of procedure */              ilist<string> deserializemessages = new list<string>();              /* first serialization issues */             mycoolobject p = jsonconvert.deserializeobject<mycoolobject>(jsoncontent,                 new jsonserializersettings                 {                     error = delegate (object sender, newtonsoft.json.serialization.erroreventargs args)                     {                         deserializemessages.add(args.errorcontext.error.message);                         args.errorcontext.handled = true;                     }                 });              ilist<string> jsonschemamessages = new list<string>();             bool jsonschemaisvalid = true;             /* now, if there no serialization issues, @ schema */             if (!deserializemessages.any())             {                 newtonsoft.json.linq.jobject jobj = newtonsoft.json.linq.jobject.parse(jsoncontent);                 jsonschemaisvalid = jobj.isvalid(jschem, out jsonschemamessages);             }              ienumerable<string> allmessages = deserializemessages.union(jsonschemamessages);              bool overallvalid = !allmessages.any();              /* end meat of procedure */ 

this gives me desired output situation:

i=0:good json yes


i=1:property 'theuuidxxx' has not been defined , schema not allow additional properties. path 'theuuidxxx', line 2, position 41.,required properties missing object: theuuid. path '', line 1, position 1.


i=2:error converting value "notaguid-3333-3333-3333-333333333333" type 'system.guid'. path 'theuuid', line 2, position 77.


i=3:unexpected character encountered while parsing value: o. path 'theinteger', line 3, position 41.,error parsing boolean value. path 'theinteger', line 3, position 42.


i=4:could not convert string datetime: notadate. path 'thedatetime', line 4, position 50.


press enter exit

i'm still wrapping head around little. in specific situation (where want response http request there json issue), works.

i won't mark "the answer" in case comes better.

note, changed loop < 5

for (int = 0; < 5; i++) 




wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -