Benzene.JsonSchema
0.0.3-alpha.4
dotnet add package Benzene.JsonSchema --version 0.0.3-alpha.4
NuGet\Install-Package Benzene.JsonSchema -Version 0.0.3-alpha.4
<PackageReference Include="Benzene.JsonSchema" Version="0.0.3-alpha.4" />
<PackageVersion Include="Benzene.JsonSchema" Version="0.0.3-alpha.4" />
<PackageReference Include="Benzene.JsonSchema" />
paket add Benzene.JsonSchema --version 0.0.3-alpha.4
#r "nuget: Benzene.JsonSchema, 0.0.3-alpha.4"
#:package Benzene.JsonSchema@0.0.3-alpha.4
#addin nuget:?package=Benzene.JsonSchema&version=0.0.3-alpha.4&prerelease
#tool nuget:?package=Benzene.JsonSchema&version=0.0.3-alpha.4&prerelease
JSON Schema Validation
JSON Schema is the standard, language-neutral way to describe and validate the shape of JSON documents. Validating with JSON Schema means the contract is the validator: the same schema document that describes a payload in your spec can reject non-conforming payloads at the door — with no C# validator classes to write, and no way for the two to drift apart.
Integration with Benzene
JSON Schema validation runs as pipeline middleware over the raw request body, before deserialization — the natural place for a document validator (it checks the wire JSON itself, so it also catches malformed or missing bodies).
For each message it obtains a schema for the current topic and evaluates the body against it. A failing body short-circuits with a ValidationError result whose payload is an array of property-scoped messages — the same failure contract as Benzene.FluentValidation and Benzene.DataAnnotations:
["/name: Value is longer than 5 characters", "/lines/0/sku: Required properties [\"sku\"] are not present"]
A null schema for a topic means "no validation" and the message passes through.
.UseJsonSchema()
.UseMessageHandlers()
Where schemas come from
- Generated (default):
DefaultJsonSchemaProviderderives a schema from the registered handler's request type (JsonSchema.Net.Generation, draft 2020-12, camelCase). - Bring your own: register hand-authored schema documents per request type — the same documents you can serve from the spec via
Benzene.Schema.OpenApi'sSuppliedSchemaCatalog, so published contract and runtime validation stay aligned:
var schemas = new SuppliedJsonSchemaCatalog()
.AddJson(typeof(CreateOrderMessage), File.ReadAllText("schemas/create-order.json"));
services.UsingBenzene(x => x.AddSuppliedJsonSchemas(schemas));
- Fully custom: implement
IJsonSchemaProvider<TContext>to source schemas from anywhere (a registry service, embedded resources, per-tenant stores).
Gap: DefaultJsonSchemaProvider does not understand System.ComponentModel.DataAnnotations
The generated (default) schema is a type-shape check only — it silently ignores
System.ComponentModel.DataAnnotations attributes. DefaultJsonSchemaProvider generates the schema
via Json.Schema.Generation's JsonSchemaBuilder().FromType(...), which recognizes only its own
attribute set (Json.Schema.Generation.Generation.* — e.g. [Required]/[Minimum]/[MinLength] from
that namespace). It does not read System.ComponentModel.DataAnnotations's attributes of the same
names ([Required], [Range], [MinLength], [StringLength], [RegularExpression], ...) — the ones
Benzene.DataAnnotations itself validates against. If your DTO is annotated with
DataAnnotations attributes (the common case — Benzene.FluentValidation rules and
System.ComponentModel.DataAnnotations attributes are the two most idiomatic ways to constrain a C#
DTO), those constraints are not enforced by Benzene.JsonSchema's default provider: a payload that
fails Benzene.DataAnnotations/Benzene.FluentValidation validation (missing required field, value
out of range, string too long, ...) can still pass Benzene.JsonSchema's generated-schema check,
because the generated schema only describes the request type's shape (property names/types/
nullability), not those attributes' constraints — with no warning at generation or validation time.
If you switch (or add) Benzene.JsonSchema expecting it to enforce the same constraints your
DataAnnotations/FluentValidation rules already do, it will not, silently, unless you close the gap
yourself:
- Supply a hand-authored schema via
SuppliedJsonSchemaCatalog(see above) that encodes the real constraints directly ("required","minLength","minimum", ...) — the most direct fix, and the one that keeps the schema as the single source of truth for the wire contract. - Annotate the DTO with
Json.Schema.Generation's own attributes (from theJson.Schema.Generationnamespace this package already depends on) alongside — or instead of — theDataAnnotationsones, soDefaultJsonSchemaProvider's generator picks the constraints up. Note this means two attribute sets on the same DTO if you also validate it withBenzene.DataAnnotationselsewhere in the pipeline. - Don't rely on
Benzene.JsonSchemaalone for a DTO that's meaningfully constrained beyond its shape — pair it withBenzene.DataAnnotations/Benzene.FluentValidationin the same pipeline (all three adapters share one short-circuit failure contract, so stacking them is safe) if you need the stronger checks and don't want to hand-author or dual-annotate the schema.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Benzene.Abstractions.Pipelines (>= 0.0.3-alpha.4)
- Benzene.Abstractions.Validation (>= 0.0.3-alpha.4)
- Benzene.Core.MessageHandlers (>= 0.0.3-alpha.4)
- Benzene.Core.Middleware (>= 0.0.3-alpha.4)
- JsonSchema.Net (>= 9.2.2)
- JsonSchema.Net.Generation (>= 7.3.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.3-alpha.4 | 36 | 9/29/2026 |
| 0.0.3-alpha.3 | 76 | 8/19/2026 |
| 0.0.3-alpha.2 | 69 | 8/19/2026 |
| 0.0.3-alpha.1 | 70 | 8/19/2026 |
| 0.0.2.18-alpha | 71 | 7/14/2026 |
| 0.0.2.17-alpha | 69 | 7/13/2026 |
| 0.0.2.16-alpha | 67 | 7/11/2026 |
| 0.0.2.15-alpha | 148 | 2/7/2025 |
| 0.0.2.14-alpha | 139 | 2/7/2025 |
| 0.0.2.13-alpha | 131 | 2/6/2025 |
| 0.0.2.12-alpha | 134 | 12/19/2024 |
| 0.0.2-alpha.6 | 62 | 8/13/2026 |
| 0.0.2-alpha.5 | 64 | 8/13/2026 |
| 0.0.2-alpha.4 | 75 | 8/10/2026 |
| 0.0.2-alpha.3 | 60 | 8/10/2026 |
| 0.0.2-alpha.2 | 63 | 7/23/2026 |
| 0.0.2-alpha.1 | 72 | 7/23/2026 |