Universal.Common.Json
1.5.0
dotnet add package Universal.Common.Json --version 1.5.0
NuGet\Install-Package Universal.Common.Json -Version 1.5.0
<PackageReference Include="Universal.Common.Json" Version="1.5.0" />
paket add Universal.Common.Json --version 1.5.0
#r "nuget: Universal.Common.Json, 1.5.0"
// Install Universal.Common.Json as a Cake Addin #addin nuget:?package=Universal.Common.Json&version=1.5.0 // Install Universal.Common.Json as a Cake Tool #tool nuget:?package=Universal.Common.Json&version=1.5.0
Universal.Common.Json
This package provides JSON Schema functionality according to the Draft 2020-12 specification, offering two distinct implementations for schema generation: JsonSchemaConverter
and SelfReferencingJsonSchemaConverter
. It includes functionality for direct schema manipulation, automatic schema generation from .NET types, and JSON validation against schemas.
Features
- Full support for JSON Schema Draft 2020-12
- Two schema converter implementations for different use cases
- Serialization and deserialization using both Newtonsoft.Json and System.Text.Json
- Extension data support for custom keywords
- Automatic schema generation from .NET types
- Support for data annotation attributes
- Comprehensive JSON validation against schemas
- JSON token extraction based on schema matching
Schema Converters
JsonSchemaConverter
The standard converter is optimized for simple to moderately complex types. It's ideal when:
- Your types don't have circular references
- You need straightforward, flat schema generation
- Performance is a priority
- You're working with DTOs or simple data models
var converter = new JsonSchemaConverter();
JsonSchema schema = converter.Convert<Person>();
SelfReferencingJsonSchemaConverter
This specialized converter handles complex object graphs and self-referencing types. Use it when:
- Your types contain circular references
- You need to handle inheritance properly
- You want schemas with shared definitions
- You're working with complex domain models
var converter = new SelfReferencingJsonSchemaConverter();
JsonSchema schema = converter.Convert<ComplexType>();
Key differences:
- Creates
$ref
references for complex types - Maintains a definitions section for reused types
- Handles circular dependencies gracefully
- May produce larger schemas due to type definitions
Usage Examples
Basic Type Conversion
// Using standard converter
var standardConverter = new JsonSchemaConverter();
var personSchema = standardConverter.Convert<Person>();
// Using self-referencing converter
var complexConverter = new SelfReferencingJsonSchemaConverter();
var orderSchema = complexConverter.Convert<Order>();
Handling Self-References
public class Employee
{
[Required]
public string Name { get; set; }
[Required]
public Employee Manager { get; set; } // Self-reference
public List<Employee> DirectReports { get; set; }
}
// Use SelfReferencingJsonSchemaConverter for this case
var converter = new SelfReferencingJsonSchemaConverter();
JsonSchema schema = converter.Convert<Employee>();
The resulting schema will include definitions to handle the self-reference:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"manager": { "$ref": "#/definitions/Employee" },
"directReports": {
"type": "array",
"items": { "$ref": "#/definitions/Employee" }
}
},
"required": ["name", "manager"],
"definitions": {
"Employee": {
"type": "object",
"properties": {
"name": { "type": "string" },
"manager": { "$ref": "#/definitions/Employee" },
"directReports": {
"type": "array",
"items": { "$ref": "#/definitions/Employee" }
}
},
"required": ["name", "manager"]
}
}
}
Complex Inheritance Example
public abstract class Vehicle
{
[Required]
public string VIN { get; set; }
public decimal Price { get; set; }
}
public class Car : Vehicle
{
public int Doors { get; set; }
public List<string> Features { get; set; }
}
public class Fleet
{
public List<Vehicle> Vehicles { get; set; }
public Car PrimaryCar { get; set; }
}
// Use SelfReferencingJsonSchemaConverter for inheritance
var converter = new SelfReferencingJsonSchemaConverter();
JsonSchema schema = converter.Convert<Fleet>();
Validation
Both schema types can be used with the validator:
var validator = new JsonSchemaValidator(schema);
var result = validator.Validate(jsonData);
if (!result.IsValid)
{
foreach (string error in result.Errors)
{
Console.WriteLine($"Validation error: {error}");
}
}
Supported Validation Attributes
Both converters support the following validation attributes:
[Required]
- Marks properties as required in the schema[StringLength]
- Sets minimum and maximum string length[MinLength]
,[MaxLength]
- Sets collection size constraints[Range]
- Sets minimum and maximum numeric values[RegularExpression]
- Sets string patterns[JsonPropertyName]
- Customizes property names in the schema[Description]
- Adds property descriptions to the schema
Best Practices
Choose the right converter:
- Use
JsonSchemaConverter
for simple types and better performance - Use
SelfReferencingJsonSchemaConverter
for complex object graphs
- Use
Consider schema size:
SelfReferencingJsonSchemaConverter
produces larger schemas due to definitions- Use it only when necessary to handle circular references or complex inheritance
Performance considerations:
JsonSchemaConverter
is more performant for simple typesSelfReferencingJsonSchemaConverter
has additional overhead for tracking references
Type organization:
- Group related types to make schemas more maintainable
- Use inheritance thoughtfully to avoid overly complex schemas
Validation attributes:
- Apply validation attributes consistently across your models
- Consider using custom attributes for special cases
Known Limitations
JsonSchemaConverter
doesn't handle circular referencesSelfReferencingJsonSchemaConverter
may produce larger schemas- Both converters have limited support for dynamic types
- Custom serialization attributes may not be fully supported
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.3)
- System.ComponentModel.Annotations (>= 5.0.0)
- System.Text.Json (>= 8.0.5)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Universal.Common.Json:
Package | Downloads |
---|---|
Universal.OpenAI.Client
Class library for interacting with OpenAI APIs. |
|
Universal.Anthropic.Client
Class library for interacting with the Anthropic REST API. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Moved recursive type support into SelfReferencingJsonSchemaConverter.
JsonSchemaConvert now maintains previous behavior.