diff --git a/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs b/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs
index 957d92e48..ee45247a5 100644
--- a/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs
+++ b/src/NJsonSchema/Generation/SampleJsonSchemaGenerator.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
@@ -33,6 +34,26 @@ public JsonSchema Generate(string json)
return schema;
}
+ /// Generates the JSON Schema for the given JSON data.
+ /// The JSON data stream.
+ /// The JSON Schema.
+ public JsonSchema Generate(Stream stream)
+ {
+ using var reader = new StreamReader(stream);
+ using var jsonReader = new JsonTextReader(reader);
+
+ var serializer = JsonSerializer.Create(new JsonSerializerSettings
+ {
+ DateFormatHandling = DateFormatHandling.IsoDateFormat
+ });
+
+ var token = serializer.Deserialize(jsonReader);
+
+ var schema = new JsonSchema();
+ Generate(token, schema, schema, "Anonymous");
+ return schema;
+ }
+
private void Generate(JToken token, JsonSchema schema, JsonSchema rootSchema, string typeNameHint)
{
if (schema != rootSchema && token.Type == JTokenType.Object)
@@ -48,7 +69,7 @@ private void Generate(JToken token, JsonSchema schema, JsonSchema rootSchema, st
s.Type == JsonObjectType.Object &&
properties.All(p => s.Properties.ContainsKey(p.Name)));
}
-
+
if (referencedSchema == null)
{
referencedSchema = new JsonSchema();
diff --git a/src/NJsonSchema/Infrastructure/JsonSchemaSerialization.cs b/src/NJsonSchema/Infrastructure/JsonSchemaSerialization.cs
index ff759f1fe..b3670e0a5 100644
--- a/src/NJsonSchema/Infrastructure/JsonSchemaSerialization.cs
+++ b/src/NJsonSchema/Infrastructure/JsonSchemaSerialization.cs
@@ -8,6 +8,7 @@
using System;
+using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
@@ -84,10 +85,10 @@ public static string ToJson(object obj, SchemaType schemaType, IContractResolver
/// The contract resolver.
/// The deserialized schema.
[Obsolete("Use FromJsonAsync with cancellation token instead.")]
- public static async Task FromJsonAsync(string json, SchemaType schemaType, string documentPath,
+ public static Task FromJsonAsync(string json, SchemaType schemaType, string documentPath,
Func referenceResolverFactory, IContractResolver contractResolver)
{
- return await FromJsonAsync(json, schemaType, documentPath, referenceResolverFactory, contractResolver, CancellationToken.None).ConfigureAwait(false);
+ return FromJsonAsync(json, schemaType, documentPath, referenceResolverFactory, contractResolver, CancellationToken.None);
}
/// Deserializes JSON data to a schema with reference handling.
@@ -98,29 +99,63 @@ public static async Task FromJsonAsync(string json, SchemaType schemaType,
/// The contract resolver.
/// The cancellation token
/// The deserialized schema.
- public static async Task FromJsonAsync(string json, SchemaType schemaType, string documentPath,
+ public static Task FromJsonAsync(string json, SchemaType schemaType, string documentPath,
Func referenceResolverFactory, IContractResolver contractResolver, CancellationToken cancellationToken = default)
+ {
+ var loader = () => FromJson(json, contractResolver);
+ return FromJsonWithLoaderAsync(loader, schemaType, documentPath, referenceResolverFactory, contractResolver, cancellationToken);
+ }
+
+ /// Deserializes JSON data to a schema with reference handling.
+ /// The JSON data stream.
+ /// The schema type.
+ /// The document path.
+ /// The reference resolver factory.
+ /// The contract resolver.
+ /// The cancellation token
+ /// The deserialized schema.
+ public static Task FromJsonAsync(Stream stream, SchemaType schemaType, string documentPath,
+ Func referenceResolverFactory, IContractResolver contractResolver, CancellationToken cancellationToken = default)
+ {
+ var loader = () => FromJson(stream, contractResolver);
+ return FromJsonWithLoaderAsync(loader, schemaType, documentPath, referenceResolverFactory, contractResolver, cancellationToken);
+ }
+
+ private static async Task FromJsonWithLoaderAsync(
+ Func loader,
+ SchemaType schemaType,
+ string documentPath,
+ Func referenceResolverFactory,
+ IContractResolver contractResolver,
+ CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
CurrentSchemaType = schemaType;
- var schema = FromJson(json, contractResolver);
- if (schema is IDocumentPathProvider documentPathProvider)
+ T schema;
+ try
{
- documentPathProvider.DocumentPath = documentPath;
- }
+ schema = loader();
+ if (schema is IDocumentPathProvider documentPathProvider)
+ {
+ documentPathProvider.DocumentPath = documentPath;
+ }
- var referenceResolver = referenceResolverFactory.Invoke(schema);
- if (schema is IJsonReference referenceSchema)
- {
- if (!string.IsNullOrEmpty(documentPath))
+ var referenceResolver = referenceResolverFactory.Invoke(schema);
+ if (schema is IJsonReference referenceSchema)
{
- referenceResolver.AddDocumentReference(documentPath, referenceSchema);
+ if (!string.IsNullOrEmpty(documentPath))
+ {
+ referenceResolver.AddDocumentReference(documentPath, referenceSchema);
+ }
}
- }
- await JsonSchemaReferenceUtilities.UpdateSchemaReferencesAsync(schema, referenceResolver, contractResolver).ConfigureAwait(false);
- CurrentSchemaType = SchemaType.JsonSchema;
+ await JsonSchemaReferenceUtilities.UpdateSchemaReferencesAsync(schema, referenceResolver, contractResolver, cancellationToken).ConfigureAwait(false);
+ }
+ finally
+ {
+ CurrentSchemaType = SchemaType.JsonSchema;
+ }
return schema;
}
@@ -132,6 +167,44 @@ public static async Task FromJsonAsync(string json, SchemaType schemaType,
public static T FromJson(string json, IContractResolver contractResolver)
{
IsWriting = true;
+ UpdateCurrentSerializerSettings(contractResolver);
+
+ try
+ {
+ return JsonConvert.DeserializeObject(json, CurrentSerializerSettings);
+ }
+ finally
+ {
+ CurrentSerializerSettings = null;
+ }
+ }
+
+ /// Deserializes JSON data with the given contract resolver.
+ /// The JSON data stream.
+ /// The contract resolver.
+ /// The deserialized schema.
+ public static T FromJson(Stream stream, IContractResolver contractResolver)
+ {
+ IsWriting = true;
+ UpdateCurrentSerializerSettings(contractResolver);
+
+ try
+ {
+ using var reader = new StreamReader(stream);
+ using var jsonReader = new JsonTextReader(reader);
+
+ var serializer = JsonSerializer.Create(CurrentSerializerSettings);
+
+ return serializer.Deserialize(jsonReader);
+ }
+ finally
+ {
+ CurrentSerializerSettings = null;
+ }
+ }
+
+ private static void UpdateCurrentSerializerSettings(IContractResolver contractResolver)
+ {
CurrentSerializerSettings = new JsonSerializerSettings
{
ContractResolver = contractResolver,
@@ -140,11 +213,6 @@ public static T FromJson(string json, IContractResolver contractResolver)
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
PreserveReferencesHandling = PreserveReferencesHandling.None
};
-
- var obj = JsonConvert.DeserializeObject(json, CurrentSerializerSettings);
- CurrentSerializerSettings = null;
-
- return obj;
}
}
}
diff --git a/src/NJsonSchema/JsonSchema.cs b/src/NJsonSchema/JsonSchema.cs
index b4e327ccb..bb7c2a10d 100644
--- a/src/NJsonSchema/JsonSchema.cs
+++ b/src/NJsonSchema/JsonSchema.cs
@@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
@@ -137,14 +138,22 @@ public static JsonSchema FromSampleJson(string data)
return generator.Generate(data);
}
+ /// Creates a from sample JSON data.
+ /// The JSON Schema.
+ public static JsonSchema FromSampleJson(Stream stream)
+ {
+ var generator = new SampleJsonSchemaGenerator();
+ return generator.Generate(stream);
+ }
+
/// Loads a JSON Schema from a given file path (only available in .NET 4.x).
/// The file path.
/// Cancellation token instance
/// The JSON Schema.
- public static async Task FromFileAsync(string filePath, CancellationToken cancellationToken = default)
+ public static Task FromFileAsync(string filePath, CancellationToken cancellationToken = default)
{
var factory = JsonReferenceResolver.CreateJsonReferenceResolverFactory(new DefaultTypeNameGenerator());
- return await FromFileAsync(filePath, factory, cancellationToken).ConfigureAwait(false);
+ return FromFileAsync(filePath, factory, cancellationToken);
}
/// Loads a JSON Schema from a given file path (only available in .NET 4.x).
@@ -153,10 +162,15 @@ public static async Task FromFileAsync(string filePath, Cancellation
/// The cancellation token
/// The JSON Schema.
/// The System.IO.File API is not available on this platform.
- public static async Task FromFileAsync(string filePath, Func referenceResolverFactory, CancellationToken cancellationToken = default)
+ public static Task FromFileAsync(string filePath, Func referenceResolverFactory, CancellationToken cancellationToken = default)
{
- var data = DynamicApis.FileReadAllText(filePath);
- return await FromJsonAsync(data, filePath, referenceResolverFactory, cancellationToken).ConfigureAwait(false);
+#if !NETSTANDARD1_0
+ using var stream = File.OpenRead(filePath);
+ return FromJsonAsync(stream, filePath, referenceResolverFactory, cancellationToken);
+#else
+ var json = DynamicApis.FileReadAllText(filePath);
+ return FromJsonAsync(json, filePath, referenceResolverFactory, cancellationToken);
+#endif
}
/// Loads a JSON Schema from a given URL (only available in .NET 4.x).
@@ -164,10 +178,10 @@ public static async Task FromFileAsync(string filePath, FuncThe cancellation token
/// The JSON Schema.
/// The HttpClient.GetAsync API is not available on this platform.
- public static async Task FromUrlAsync(string url, CancellationToken cancellationToken = default)
+ public static Task FromUrlAsync(string url, CancellationToken cancellationToken = default)
{
var factory = JsonReferenceResolver.CreateJsonReferenceResolverFactory(new DefaultTypeNameGenerator());
- return await FromUrlAsync(url, factory, cancellationToken).ConfigureAwait(false);
+ return FromUrlAsync(url, factory, cancellationToken);
}
/// Loads a JSON Schema from a given URL (only available in .NET 4.x).
@@ -186,9 +200,19 @@ public static async Task FromUrlAsync(string url, FuncThe JSON string.
/// The cancellation token
/// The JSON Schema.
- public static async Task FromJsonAsync(string data, CancellationToken cancellationToken = default)
+ public static Task FromJsonAsync(string data, CancellationToken cancellationToken = default)
{
- return await FromJsonAsync(data, null, cancellationToken).ConfigureAwait(false);
+ return FromJsonAsync(data, null, cancellationToken);
+ }
+
+ /// Deserializes a JSON stream to a .
+ /// The JSON data stream.
+ /// The cancellation token
+ /// The JSON Schema.
+ public static Task FromJsonAsync(Stream stream, CancellationToken cancellationToken = default)
+ {
+ var factory = JsonReferenceResolver.CreateJsonReferenceResolverFactory(new DefaultTypeNameGenerator());
+ return FromJsonAsync(stream, null, factory, cancellationToken);
}
/// Deserializes a JSON string to a .
@@ -196,10 +220,10 @@ public static async Task FromJsonAsync(string data, CancellationToke
/// The document path (URL or file path) for resolving relative document references.
/// The cancellation token
/// The JSON Schema.
- public static async Task FromJsonAsync(string data, string documentPath, CancellationToken cancellationToken = default)
+ public static Task FromJsonAsync(string data, string documentPath, CancellationToken cancellationToken = default)
{
var factory = JsonReferenceResolver.CreateJsonReferenceResolverFactory(new DefaultTypeNameGenerator());
- return await FromJsonAsync(data, documentPath, factory, cancellationToken).ConfigureAwait(false);
+ return FromJsonAsync(data, documentPath, factory, cancellationToken);
}
/// Deserializes a JSON string to a .
@@ -208,10 +232,22 @@ public static async Task FromJsonAsync(string data, string documentP
/// The JSON reference resolver factory.
/// The cancellation token
/// The JSON Schema.
- public static async Task FromJsonAsync(string data, string documentPath, Func FromJsonAsync(string data, string documentPath, Func referenceResolverFactory, CancellationToken cancellationToken = default)
+ {
+ return JsonSchemaSerialization.FromJsonAsync(data, SerializationSchemaType, documentPath, referenceResolverFactory, ContractResolver.Value, cancellationToken);
+ }
+
+ /// Deserializes a JSON string to a .
+ /// The JSON data stream.
+ /// The document path (URL or file path) for resolving relative document references.
+ /// The JSON reference resolver factory.
+ /// The cancellation token
+ /// The JSON Schema.
+ public static Task FromJsonAsync(Stream stream, string documentPath, Func referenceResolverFactory, CancellationToken cancellationToken = default)
{
- return await JsonSchemaSerialization.FromJsonAsync(data, SerializationSchemaType, documentPath, referenceResolverFactory, ContractResolver.Value, cancellationToken).ConfigureAwait(false);
+ return JsonSchemaSerialization.FromJsonAsync(stream, SerializationSchemaType, documentPath, referenceResolverFactory, ContractResolver.Value, cancellationToken);
}
internal static JsonSchema FromJsonWithCurrentSettings(object obj)