Purview.ZodSharp.Extensions.Validation
3.0.0-prerelease.2
dotnet add package Purview.ZodSharp.Extensions.Validation --version 3.0.0-prerelease.2
NuGet\Install-Package Purview.ZodSharp.Extensions.Validation -Version 3.0.0-prerelease.2
<PackageReference Include="Purview.ZodSharp.Extensions.Validation" Version="3.0.0-prerelease.2" />
<PackageVersion Include="Purview.ZodSharp.Extensions.Validation" Version="3.0.0-prerelease.2" />
<PackageReference Include="Purview.ZodSharp.Extensions.Validation" />
paket add Purview.ZodSharp.Extensions.Validation --version 3.0.0-prerelease.2
#r "nuget: Purview.ZodSharp.Extensions.Validation, 3.0.0-prerelease.2"
#:package Purview.ZodSharp.Extensions.Validation@3.0.0-prerelease.2
#addin nuget:?package=Purview.ZodSharp.Extensions.Validation&version=3.0.0-prerelease.2&prerelease
#tool nuget:?package=Purview.ZodSharp.Extensions.Validation&version=3.0.0-prerelease.2&prerelease
Purview.ZodSharp.Extensions.Validation
Microsoft.Extensions.Validation integration for
Purview.ZodSharp. It registers ZodSharp as the first .NET 11
validation resolver, so minimal APIs, Blazor Server and Blazor WebAssembly validate every type that has a
ZodSharp validator with ZodSharp - nested objects, collections and dictionaries included - without
[ValidatableType] and without the Microsoft.Extensions.Validation source generator.
Targets net11.0. It references the Microsoft.Extensions.Validation package, never the ASP.NET Core shared
framework, so it works in a Blazor WebAssembly client and in worker or console hosts.
Installation
dotnet add package Purview.ZodSharp.Extensions.Validation
Usage
builder.Services.AddZodSharpFactory(factory => factory.Register(new OrderSchemaValidator()));
builder.Services.AddZodSharpValidation();
// Keep calling AddValidation() in the application when DataAnnotations types should be validated too:
// the Microsoft.Extensions.Validation generator only intercepts calls in your own code.
builder.Services.AddValidation();
ZodSharp's resolver ends up first whether AddValidation() is called before AddZodSharpValidation(), after it,
or not at all. Types without a ZodSharp validator fall through to the next resolver.
This turns on minimal-API validation for every ZodSharp-typed handler parameter: the platform's endpoint filter
validates every parameter a resolver claims, before the handler runs. Opt endpoints out with DisableValidation(), or
register type validation only with AddZodSharpValidation(configure, validateParameters: false) (what
AddZodSharpBlazor() does) or ValidateParameters = false.
For trimmed and Native AOT apps (including Blazor WebAssembly), register the generated validators with the
per-assembly extension the source generator emits instead of scanning: builder.Services.AddZodSharpMyAppSchemas();
(AddZodSharp{Assembly}Schemas(), the assembly name in PascalCase). [ValidatableType] is not needed on a
[ZodSchema] type, and is reported as redundant (ZODSGEN047).
What each error carries
ValidationError |
Value |
|---|---|
Path |
The ZodSharp path, prefixed with ValidateContext.CurrentValidationPath: Customer.Address.Street, Lines[0].Sku, ByCode[abc].Sku |
Name |
The failing member's name (Street); empty for a model-level error |
Container |
The object that owns the member (order.Customer.Address), which is what Blazor uses to place the message on the right field. Never a struct: an error inside a struct member (Email.Value) belongs to the nearest reference-type owner and its member (Email) |
ErrorMessage |
The ZodSharp message, localized when an IStringLocalizerFactory is registered (see below) |
Runtime Z.Object() schemas over dictionaries have no owning object, so their errors carry Container = null
and the full path as Name: Blazor shows them in the validation summary.
Parameters follow Microsoft.Extensions.Validation's conventions: a complex parameter is not prefixed, a
collection parameter is (items[0].Name), and an error about the value itself is keyed by the parameter name.
Full-fidelity errors
Microsoft.Extensions.Validation keeps only a name, path, message and container. The full ZodSharp errors - code, category, origin, bounds and parameters - are available alongside:
ValidateContext context = new() { ValidationOptions = options, ServiceProvider = services };
await typeInfo.ValidateAsync(order, context, cancellationToken);
ZodValidationReport? report = context.ZodReport;
Register an IZodValidationReportSink with a per-run lifetime (a scoped service in ASP.NET Core) to receive the
same errors where the ValidateContext is created for you. Do not register one in Blazor Server, where the scope is
the circuit. Outside HTTP and Blazor, ValidationOptions.ValidateAsync(value, services) validates and returns the
report directly:
var options = services.GetRequiredService<IOptions<ValidationOptions>>().Value;
ZodValidationReport report = await options.ValidateAsync(order, services, cancellationToken);
foreach (var error in report.Errors)
Console.WriteLine($"{error.FullPath.ToDottedString()}: {error.Message} ({error.Code})");
Errors from other resolvers (DataAnnotations types) are included with code custom, their path parsed from the
Microsoft.Extensions.Validation key.
Localization
When the validation's service provider resolves an IStringLocalizerFactory, messages are localized by
StringLocalizerZodMessageFormatter, honouring ValidationOptions.LocalizerProvider. Keys are tried in order:
the message template, {Type}_{Member}_{Code}, {Type}_{Code}, {Code}; otherwise the ZodSharp message is
kept. Set ZodValidationOptions.MessageFormatter to replace it.
Options
| Option | Default | Effect |
|---|---|---|
Placement |
First |
AfterGenerated places ZodSharp after the generated DataAnnotations resolvers |
AlsoRunDataAnnotations |
false |
Also runs the next resolver for ZodSharp types, reporting identical messages once |
PathNamer |
null (C# names) |
Renames members in Path, for example to camelCase |
MessageFormatter |
null |
Formats every message |
Sources |
empty | Trim-safe validator sources consulted before IZodSchemaFactory |
ValidateParameters |
null (by registration) |
Whether minimal-API parameters are claimed (endpoint validation): on after AddZodSharpValidation(), off when only AddZodSharpBlazor() registered the bridge |
Register every validator before the first validation: lookups are cached, including misses. Synchronous
validation of a type with asynchronous rules throws, as EditContext.Validate() does; use the async APIs.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net11.0 is compatible. |
-
net11.0
- Microsoft.Extensions.Validation (>= 11.0.0-rc.3.26522.148)
- Purview.ZodSharp (>= 3.0.0-prerelease.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Purview.ZodSharp.Extensions.Validation:
| Package | Downloads |
|---|---|
|
Purview.ZodSharp.AspNetCore
ASP.NET Core ProblemDetails integration for ZodSharp validation results. |
|
|
Purview.ZodSharp.Blazor
Blazor integration for ZodSharp: validates EditForm models with ZodSharp on Blazor Server, Blazor WebAssembly and Auto render mode, through the standard DataAnnotationsValidator or the full-fidelity ZodValidator, and maps API validation problems back onto form fields. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-prerelease.2 | 82 | 11/2/2026 |