Esempio n. 1
0
        public void UnevaluatedProperties_NestedAdditionalProperties_Match()
        {
            string schemaJson = @"{
                ""type"": ""object"",
                ""properties"": {
                    ""foo"": { ""type"": ""string"" }
                },
                ""allOf"": [
                    {
                        ""additionalProperties"": true
                    }
                ],
                ""unevaluatedProperties"": false
            }";

            string json = @"{
                    ""foo"": ""foo"",
                    ""bar"": ""bar""
                }";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            while (reader.Read())
            {
            }

            Assert.IsNull(validationEventArgs);
        }
Esempio n. 2
0
        public void UnevaluatedItems_Schema_Match()
        {
            string schemaJson = @"{
                ""type"": ""array"",
                ""unevaluatedItems"": {
                    ""type"": ""string"",
                    ""minLength"": 3
                }
            }";

            string json = @"[ ""foo"" ]";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            while (reader.Read())
            {
            }

            Assert.IsNull(validationEventArgs);
        }
        public void ReadSpecTest(SchemaSpecTest schemaSpecTest)
        {
            Console.WriteLine("Running reader JSON Schema {0} test {1}: {2}", schemaSpecTest.Version, schemaSpecTest.TestNumber, schemaSpecTest);

            IList <string> errorMessages = new List <string>();

            JSchemaPreloadedResolver resolver = GetResolver();

            JSchema s = JSchema.Load(schemaSpecTest.Schema.CreateReader(), resolver);

            s.SchemaVersion = GetSchemaUri(schemaSpecTest.Version);

            JsonReader jsonReader = schemaSpecTest.Data.CreateReader();

            using (JSchemaValidatingReader reader = new JSchemaValidatingReader(jsonReader))
            {
                reader.Schema = s;
                reader.ValidationEventHandler += (sender, args) => errorMessages.Add(args.Message);

                while (reader.Read())
                {
                }
            }

            bool isValid = (errorMessages.Count == 0);

            Assert.AreEqual(schemaSpecTest.IsValid, isValid, schemaSpecTest.TestCaseDescription + " - " + schemaSpecTest.TestDescription + " - errors: " + StringHelpers.Join(", ", errorMessages));
        }
Esempio n. 4
0
        public void Test_Complex()
        {
            var schema  = JSchema.Parse(@"{
    allOf: [
        {type:'object',properties: { a: {type: 'integer'}, b: {type:'integer'}}},
        {type:'object',properties: { a: {type: 'integer'}, b: {type:'integer'}}}
    ]
}");
            var content = @"{a: 1, b: 1}  {'a': true, b: 1}";

            using (var reader = new JsonTextReader(new StringReader(content))
            {
                SupportMultipleContent = true
            })
                using (var vreader = new JSchemaValidatingReader(reader)
                {
                    Schema = schema, SupportMultipleContent = true
                })
                {
                    var count = 0;
                    vreader.ValidationEventHandler += (o, a) => { count++; System.Console.WriteLine(a.Message); };

                    while (vreader.Read())
                    {
                        System.Console.WriteLine(vreader.TokenType);
                    }
                    System.Console.WriteLine("Done, {0} error(s)", count);
                }
        }
        private void ReaderValidation()
        {
            JsonTextReader reader = new JsonTextReader(new StringReader(Json));
            JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
            validatingReader.Schema = Schema;

            while (validatingReader.Read())
            {
            }
        }
Esempio n. 6
0
        private void ReaderValidation()
        {
            JsonTextReader          reader           = new JsonTextReader(new StringReader(Json));
            JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);

            validatingReader.Schema = Schema;

            while (validatingReader.Read())
            {
            }
        }
        public void UnevaluatedProperties_NotAllowed_AllOfProperties_Match()
        {
            string schemaJson = @"{
                ""type"": ""object"",
                ""properties"": {
                    ""foo"": { ""type"": ""string"" }
                },
                ""allOf"": [
                    {
                        ""properties"": {
                            ""bar"": { ""type"": ""string"" }
                        }
                    }
                ],
                ""unevaluatedProperties"": false
            }";

            string json = "{'bar':'value'}";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            Assert.IsTrue(reader.Read());
            Assert.AreEqual(JsonToken.StartObject, reader.TokenType);

            Assert.IsTrue(reader.Read());
            Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
            Assert.IsTrue(reader.Read());
            Assert.AreEqual(JsonToken.String, reader.TokenType);

            Assert.IsTrue(reader.Read());
            Assert.AreEqual(JsonToken.EndObject, reader.TokenType);

            Assert.IsNull(validationEventArgs);
        }
Esempio n. 8
0
        private static void ReaderValidation(string json, JSchema schema)
        {
            List <ValidationError> errors = new List <ValidationError>();

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (o, e) => errors.Add(e.ValidationError);
            reader.Schema = schema;

            while (reader.Read())
            {
            }
        }
        public void UnevaluatedProperties_AnyOf_NoMatch()
        {
            string schemaJson = @"{
                ""type"": ""object"",
                ""properties"": {
                    ""foo"": { ""type"": ""string"" }
                },
                ""anyOf"": [
                    {
                        ""properties"": {
                            ""bar"": { ""const"": ""bar"" }
                        },
                        ""required"": [""bar""]
                    },
                    {
                        ""properties"": {
                            ""baz"": { ""const"": ""baz"" }
                        },
                        ""required"": [""baz""]
                    },
                    {
                        ""properties"": {
                            ""quux"": { ""const"": ""quux"" }
                        },
                        ""required"": [""quux""]
                    }
                ],
                ""unevaluatedProperties"": false
            }";

            string json = @"{
                    ""foo"": ""foo"",
                    ""bar"": ""bar"",
                    ""baz"": ""not-baz""
                }";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            while (reader.Read())
            {
            }

            Assert.IsNotNull(validationEventArgs);
            Assert.AreEqual("Property 'baz' has not been successfully evaluated and the schema does not allow unevaluated properties. Path '', line 5, position 17.", validationEventArgs.Message);
            Assert.AreEqual(ErrorType.UnevaluatedProperties, validationEventArgs.ValidationError.ErrorType);
        }
Esempio n. 10
0
 private void ValidateObject(object obj, SchemaValidationEventHandler validationEventHandler)
 {
     using (var reader = new JSchemaValidatingReader(new ObjectJsonReader(obj)))
     {
         reader.Schema = _jSchema;
         if (validationEventHandler != null)
         {
             reader.ValidationEventHandler += validationEventHandler;
         }
         while (reader.Read())
         {
         }
     }
 }
Esempio n. 11
0
        private void ValidateObject(object obj, JSchema schema, SchemaValidationEventHandler validationEventHandler)
        {
            var jsonReader = obj is JObject jo?jo.CreateReader() : new IgnoreStrongTypeObjectJsonReader(obj);

            using var reader = new JSchemaValidatingReader(jsonReader);
            reader.Schema    = schema;
            if (validationEventHandler != null)
            {
                reader.ValidationEventHandler += validationEventHandler;
            }
            while (reader.Read())
            {
            }
        }
        public void BigNum()
        {
            ValidationError error = null;

            JSchema s = JSchema.Parse(@"{""maximum"": 18446744073709551615}");

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader("18446744073709551600")));

            reader.Schema = s;
            reader.ValidationEventHandler += (sender, args) => { error = args.ValidationError; };

            Assert.IsTrue(reader.Read());
            Assert.IsNull(error);
        }
        public void UnevaluatedProperties_HasUnevaluatedProperty_AllowAllSchema()
        {
            string schemaJson = @"{
                ""type"": ""object"",
                ""properties"": {
                    ""foo"": { ""type"": ""string"" }
                },
                ""anyOf"": [
                    {
                        ""properties"": {
                            ""bar"": { ""const"": ""bar"" }
                        },
                        ""required"": [""bar""]
                    },
                    {
                        ""properties"": {
                            ""baz"": { ""const"": ""baz"" }
                        },
                        ""required"": [""baz""]
                    },
                    {
                        ""properties"": {
                            ""quux"": { ""const"": ""quux"" }
                        },
                        ""required"": [""quux""]
                    }
                ],
                ""unevaluatedProperties"": {}
            }";

            string json = @"{
                    ""foo"": ""foo"",
                    ""bar"": ""bar"",
                    ""baz"": ""not-baz""
                }";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            while (reader.Read())
            {
            }

            Assert.IsNull(validationEventArgs);
        }
        public void Validate(JSchema schema, JToken value)
        {
            _errors.Clear();

            if (schema != null)
            {
                using (var reader = new JSchemaValidatingReader(value.CreateReader()))
                {
                    reader.Schema = schema;
                    reader.ValidationEventHandler += OnValidationError;

                    while (reader.Read())
                    {
                        ;
                    }
                }
            }
        }
        public static IList <ValidationError> Validate(Stream reader, JSchema schema)
        {
            IList <ValidationError> validationErrors = new List <ValidationError>();

            using (StreamReader bufferReader = new StreamReader(reader, Encoding.UTF8, true, 1024, leaveOpen: true))
            {
                JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(new JsonTextReader(bufferReader));
                validatingReader.Schema = schema;
                validatingReader.ValidationEventHandler += (sender, args) =>
                {
                    validationErrors.Add(args.ValidationError);
                };

                while (validatingReader.Read())
                {
                }
            }

            return(validationErrors);
        }
        public void UnevaluatedProperties_DependentSchemas_NoUnevaluatedProperties()
        {
            string schemaJson = @"{
                ""type"": ""object"",
                ""properties"": {
                    ""foo"": { ""type"": ""string"" }
                },
                ""dependentSchemas"": {
                    ""foo"": {
                        ""properties"": {
                            ""bar"": { ""const"": ""bar"" }
                        },
                        ""required"": [""bar""]
                    }
                },
                ""unevaluatedProperties"": false
            }";

            string json = @"{
                    ""foo"": ""foo"",
                    ""bar"": ""bar""
                }";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            while (reader.Read())
            {
            }

            Assert.IsNull(validationEventArgs);
        }
        public void ReaderPerformance()
        {
            string json = @"[
    {
        ""id"": 2,
        ""name"": ""An ice sculpture"",
        ""price"": 12.50,
        ""tags"": [""cold"", ""ice""],
        ""dimensions"": {
            ""length"": 7.0,
            ""width"": 12.0,
            ""height"": 9.5
        },
        ""warehouseLocation"": {
            ""latitude"": -78.75,
            ""longitude"": 20.4
        }
    },
    {
        ""id"": 3,
        ""name"": ""A blue mouse"",
        ""price"": 25.50,
        ""dimensions"": {
            ""length"": 3.1,
            ""width"": 1.0,
            ""height"": 1.0
        },
        ""warehouseLocation"": {
            ""latitude"": 54.4,
            ""longitude"": -32.7
        }
    }
]";

            JSchema schema = JSchema.Parse(@"{
    ""$schema"": ""http://json-schema.org/draft-04/schema#"",
    ""title"": ""Product set"",
    ""type"": ""array"",
    ""items"": {
        ""title"": ""Product"",
        ""type"": ""object"",
        ""properties"": {
            ""id"": {
                ""description"": ""The unique identifier for a product"",
                ""type"": ""number""
            },
            ""name"": {
                ""type"": ""string""
            },
            ""price"": {
                ""type"": ""number"",
                ""minimum"": 0,
                ""exclusiveMinimum"": true
            },
            ""tags"": {
                ""type"": ""array"",
                ""items"": {
                    ""type"": ""string""
                },
                ""minItems"": 1,
                ""uniqueItems"": true
            },
            ""dimensions"": {
                ""type"": ""object"",
                ""properties"": {
                    ""length"": {""type"": ""number""},
                    ""width"": {""type"": ""number""},
                    ""height"": {""type"": ""number""}
                },
                ""required"": [""length"", ""width"", ""height""]
            },
            ""warehouseLocation"": {
                ""description"": ""A geographical coordinate"",
                ""type"": ""object"",
                ""properties"": {
                    ""latitude"": { ""type"": ""number"" },
                    ""longitude"": { ""type"": ""number"" }
                }
            }
        },
        ""required"": [""id"", ""name"", ""price""]
    }
}");

            using (var tester = new PerformanceTester("Reader"))
            {
                for (int i = 0; i < 1000; i++)
                {
                    JsonTextReader          reader           = new JsonTextReader(new StringReader(json));
                    JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
                    validatingReader.Schema = schema;

                    while (validatingReader.Read())
                    {
                    }
                }
            }
        }
        public void SchemaReused_UnevaluatedProperties()
        {
            string schemaJson = @"{
  ""type"": ""object"",
  ""definitions"": {
    ""allRegionProperties"": {
      ""properties"": {
        ""Type"": true,
        ""Slug"": true
      }
    }
  },
  ""required"": [
    ""Type""
  ],
  ""properties"": {
    ""Type"": {
      ""enum"": [
        ""region"",
        ""geo"",
        ""non-regional""
      ]
    }
  },
  ""oneOf"": [
    {
      ""if"": {
        ""properties"": {
          ""Type"": {
            ""enum"": [
              ""geo""
            ]
          }
        }
      },
      ""then"": {
        ""$ref"": ""#/definitions/allRegionProperties"",
        ""unevaluatedProperties"": false
      },
      ""else"": false
    },
    {
      ""if"": {
        ""properties"": {
          ""Type"": {
            ""enum"": [
              ""non-regional""
            ]
          }
        }
      },
      ""then"": {
        ""allOf"": [
          {
            ""$ref"": ""#/definitions/allRegionProperties"",
            ""unevaluatedProperties"": false
          }
        ]
      },
      ""else"": false
    }
  ]
}";

            string json = @"{
  ""Type"": ""non-regional"",
  ""Unknown"": ""2 spooky""
}";

            SchemaValidationEventArgs validationEventArgs = null;

            JSchemaValidatingReader reader = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)));

            reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
            reader.Schema = JSchema.Parse(schemaJson);

            while (reader.Read())
            {
            }

            Assert.IsNotNull(validationEventArgs);
            Assert.AreEqual("JSON is valid against no schemas from 'oneOf'.", validationEventArgs.ValidationError.Message);
            Assert.AreEqual("JSON does not match schema from 'then'.", validationEventArgs.ValidationError.ChildErrors[0].Message);
            Assert.AreEqual("JSON does not match all schemas from 'allOf'. Invalid schema indexes: 0.", validationEventArgs.ValidationError.ChildErrors[0].ChildErrors[0].Message);
            Assert.AreEqual("Property 'Unknown' has not been successfully evaluated and the schema does not allow unevaluated properties.", validationEventArgs.ValidationError.ChildErrors[0].ChildErrors[0].ChildErrors[0].Message);
        }
        public void ReaderPerformance()
        {
            string json = @"[
    {
        ""id"": 2,
        ""name"": ""An ice sculpture"",
        ""price"": 12.50,
        ""tags"": [""cold"", ""ice""],
        ""dimensions"": {
            ""length"": 7.0,
            ""width"": 12.0,
            ""height"": 9.5
        },
        ""warehouseLocation"": {
            ""latitude"": -78.75,
            ""longitude"": 20.4
        }
    },
    {
        ""id"": 3,
        ""name"": ""A blue mouse"",
        ""price"": 25.50,
        ""dimensions"": {
            ""length"": 3.1,
            ""width"": 1.0,
            ""height"": 1.0
        },
        ""warehouseLocation"": {
            ""latitude"": 54.4,
            ""longitude"": -32.7
        }
    }
]";

            JSchema schema = JSchema.Parse(@"{
    ""$schema"": ""http://json-schema.org/draft-04/schema#"",
    ""title"": ""Product set"",
    ""type"": ""array"",
    ""items"": {
        ""title"": ""Product"",
        ""type"": ""object"",
        ""properties"": {
            ""id"": {
                ""description"": ""The unique identifier for a product"",
                ""type"": ""number""
            },
            ""name"": {
                ""type"": ""string""
            },
            ""price"": {
                ""type"": ""number"",
                ""minimum"": 0,
                ""exclusiveMinimum"": true
            },
            ""tags"": {
                ""type"": ""array"",
                ""items"": {
                    ""type"": ""string""
                },
                ""minItems"": 1,
                ""uniqueItems"": true
            },
            ""dimensions"": {
                ""type"": ""object"",
                ""properties"": {
                    ""length"": {""type"": ""number""},
                    ""width"": {""type"": ""number""},
                    ""height"": {""type"": ""number""}
                },
                ""required"": [""length"", ""width"", ""height""]
            },
            ""warehouseLocation"": {
                ""description"": ""A geographical coordinate"",
                ""type"": ""object"",
                ""properties"": {
                    ""latitude"": { ""type"": ""number"" },
                    ""longitude"": { ""type"": ""number"" }
                }
            }
        },
        ""required"": [""id"", ""name"", ""price""]
    }
}");

            using (var tester = new PerformanceTester("Reader"))
            {
                for (int i = 0; i < 1000; i++)
                {
                    JsonTextReader reader = new JsonTextReader(new StringReader(json));
                    JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
                    validatingReader.Schema = schema;

                    while (validatingReader.Read())
                    {
                    }
                }
            }
        }
Esempio n. 20
0
        private void validate(string baseDir, string nameSpace)
        {
            var schemas  = Path.Combine(baseDir, "schemas");
            var resolver = new Resolver(schemas);

            foreach (var example in Directory.EnumerateFiles(Path.Combine(baseDir, "examples")))
            {
                var exampleFile = Path.GetFileName(example);
                switch (exampleFile)
                {
                //Items in examples are out of date
                case "candidateEdit-simple.json":
                case "candidateEditSpec-additional.json":
                case "candidateEditSpec-apply.json":
                case "candidateEditSpec-ATSData.json":
                case "candidateEditSpec-register.json":
                case "candidateEditSpec-registeradditional.json":

                //Invalid enum values
                case "rebootStatus-juggleApps.json":
                case "rebootStatus-simpleReboot.json":
                case "rebootStatus-bumpSecurityGeneration.json":

                //Required fields are null
                case "assessmentRead-created.json":
                case "assessmentWriteByApp-completed.json":
                case "assessmentWriteByApp-underway.json":
                case "candidateFace-simple.json":
                    continue;
                }

                var schema = Path.Combine(schemas, GetSchemaName(exampleFile));
                if (schema.EndsWith("Read.json") || schema.EndsWith("Write.json"))
                {
                    //probably contains items, and thus is affected by
                    //https://github.com/RSuter/NJsonSchema/pull/628
                    continue;
                }
                switch (Path.GetFileName(schema))
                {
                //https://github.com/RSuter/NJsonSchema/pull/628
                case "tenantExtended.json":

                //Degenerate inheritance
                case "assertionHooks.json":
                case "patchSet.json":
                case "patchSetPreparer.json":
                    continue;
                }
                Type valueType;
                try
                {
                    valueType = GetValueType(nameSpace, schema);
                    Console.WriteLine("Validating " + example + " against " + (typeof(IList).IsAssignableFrom(valueType) ? "collection type " : "") + schema);
                }
                catch (FileNotFoundException)
                {
                    Console.WriteLine("No schema found for " + Path.GetFileName(example));
                    continue;
                }
                catch (Exception e)
                {
                    throw new Exception("Error resolving schema for " + Path.GetFileName(example), e);
                }


                var poco = JsonConvert.DeserializeObject(File.ReadAllText(example), valueType);
                var json = JsonConvert.SerializeObject(poco, new JsonSerializerSettings()
                {
                    Converters = new[] { new StringEnumConverter() }, ContractResolver = new IgnoreEmptyArrays()
                });
                var validator = new JSchemaValidatingReader(new JsonTextReader(new StringReader(json)))
                {
                    Schema = JSchema.Parse(File.ReadAllText(schema), resolver)
                };


                try
                {
                    while (validator.Read())
                    {
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(json);
                    Assert.True(false, e.Message);
                }
                Assert.True(valueType.IsInstanceOfType(poco));

                if (exampleFile == "categoryValuesUpload-mockLocations.json")
                {
                    //https://github.com/JamesNK/Newtonsoft.Json/issues/1007
                    return;
                }
                Assert.True(JToken.DeepEquals(JToken.Parse(json), JToken.Parse(File.ReadAllText(example))), example + " equals " + json);
            }
        }
Esempio n. 21
0
        public void IsValidPerformance()
        {
            JArray a = JArray.Parse(Json);

            a.IsValid(Schema);
            a.IsValid(SchemaV3);

            using (new PerformanceTester("Raw"))
            {
                for (int i = 1; i < ValidationCount; i++)
                {
                    JsonTextReader reader = new JsonTextReader(new StringReader(Json));

                    while (reader.Read())
                    {
                    }
                }
            }

            GC.Collect();

            using (new PerformanceTester("JSchema"))
            {
                for (int i = 1; i < ValidationCount; i++)
                {
                    JsonTextReader reader = new JsonTextReader(new StringReader(Json));

                    JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
                    validatingReader.Schema = Schema;
                    while (validatingReader.Read())
                    {
                    }
                }
            }

            GC.Collect();

            using (new PerformanceTester("JsonSchema"))
            {
                for (int i = 1; i < ValidationCount; i++)
                {
                    JsonTextReader reader = new JsonTextReader(new StringReader(Json));

                    JsonValidatingReader vr = new JsonValidatingReader(reader);
                    vr.Schema = SchemaV3;
                    while (vr.Read())
                    {
                    }
                }
            }

            XmlSchema schema = XmlSchema.Read(new StringReader(SchemaXml), (sender, args) =>
            {
                throw new Exception(args.Message);
            });
            XmlSchemaSet set = new XmlSchemaSet();

            set.Add(schema);
            set.Compile();

            GC.Collect();

            using (new PerformanceTester("IsValid_XmlSchema"))
            {
                for (int i = 1; i < ValidationCount; i++)
                {
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.ValidationType          = ValidationType.Schema;
                    settings.Schemas                 = set;
                    settings.ValidationEventHandler += ValidatingReader_ValidationEventHandler;

                    XmlReader reader = XmlReader.Create(new StringReader(Xml), settings);

                    while (reader.Read())
                    {
                    }
                }
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Save a log from a stream to the filesystem, also validates the data.
        /// </summary>
        /// <param name="stream">The stream where the log is found.</param>
        /// <returns>Returns the log's unique id to use when requesting it from storage.</returns>
        public static string PutFromStream(Stream stream)
        {
            string logID;
            string path;

            do
            {
                logID = Guid.NewGuid().ToString("D");
                path  = Path.Combine(AppDataDir, logID);
            } while (File.Exists(path));

            try
            {
                var s      = new StreamReader(stream);
                var reader = new JSchemaValidatingReader(new JsonTextReader(s));
                using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
                    using (var w = new StreamWriter(fs))
                        using (var writer = new JsonTextWriter(w))
                        {
                            reader.Schema = Schema;
                            reader.ValidationEventHandler += (sender, args) => throw new JsonException();

                            while (reader.Read())
                            {
                                switch (reader.TokenType)
                                {
                                case JsonToken.None:
                                    break;

                                case JsonToken.StartObject:
                                    writer.WriteStartObject();
                                    break;

                                case JsonToken.StartArray:
                                    writer.WriteStartArray();
                                    break;

                                case JsonToken.StartConstructor:
                                    writer.WriteStartConstructor(reader.Value.ToString());
                                    break;

                                case JsonToken.PropertyName:
                                    writer.WritePropertyName(reader.Value.ToString());
                                    break;

                                case JsonToken.Comment:
                                    writer.WriteComment(reader.Value.ToString());
                                    break;

                                case JsonToken.Raw:
                                    writer.WriteRaw(reader.Value.ToString());
                                    break;

                                case JsonToken.Integer:
                                    writer.WriteValue(reader.Value);
                                    break;

                                case JsonToken.Float:
                                    writer.WriteValue(reader.Value);
                                    break;

                                case JsonToken.String:
                                    writer.WriteValue(reader.Value);
                                    break;

                                case JsonToken.Boolean:
                                    writer.WriteValue(reader.Value);
                                    break;

                                case JsonToken.Null:
                                    writer.WriteNull();
                                    break;

                                case JsonToken.Undefined:
                                    writer.WriteUndefined();
                                    break;

                                case JsonToken.EndObject:
                                    writer.WriteEndObject();
                                    break;

                                case JsonToken.EndArray:
                                    writer.WriteEndArray();
                                    break;

                                case JsonToken.EndConstructor:
                                    writer.WriteEndConstructor();
                                    break;

                                case JsonToken.Date:
                                    writer.WriteValue(reader.Value);
                                    break;

                                case JsonToken.Bytes:
                                    writer.WriteValue(reader.Value);
                                    break;

                                default:
                                    throw new ArgumentOutOfRangeException();
                                }
                            }
                        }
            }
            catch (JsonException)
            {
                File.Delete(path);
                throw;
            }
            catch (IOException e)
            {
                if (e.HResult != -2146232800)
                {
                    throw;
                }
            }

            return(logID);
        }