MicroElements.OpenApi.FluentValidation 7.2.2

Package Description

Showing the top 20 packages that depend on MicroElements.OpenApi.FluentValidation.

Packages Downloads
MicroElements.Swashbuckle.FluentValidation
Swagger ISchemaFilter that uses FluentValidation validators instead System.ComponentModel based attributes.
1
MicroElements.Swashbuckle.FluentValidation
Swagger ISchemaFilter that uses FluentValidation validators instead System.ComponentModel based attributes.
4
MicroElements.Swashbuckle.FluentValidation
Swagger ISchemaFilter that uses FluentValidation validators instead System.ComponentModel based attributes.
57
MicroElements.Swashbuckle.FluentValidation
Swagger ISchemaFilter that uses FluentValidation validators instead System.ComponentModel based attributes.
100
MicroElements.Swashbuckle.FluentValidation
Swagger ISchemaFilter that uses FluentValidation validators instead System.ComponentModel based attributes.
413

$# Changes in 7.2.2

  • Fixed: MicroElements.AspNetCore.OpenApi.FluentValidation did not apply FluentValidation rules to a [FromForm] DTO bound by an MVC controller action (Issue #232, follow-up to the Swashbuckle-only #170 fix)
    • Root cause: MVC ApiExplorer flattens a controller's [FromForm] complex parameter into one form field per property, so Microsoft.AspNetCore.OpenApi builds the request body as an inline schema from those descriptions and never asks for the DTO's JsonTypeInfo — FluentValidationSchemaTransformer therefore never saw the type. Minimal API form bodies are not flattened and were never affected
    • Fix: FluentValidationOperationTransformer now applies the DTO's rules to the inline form schema for both multipart/form-data and application/x-www-form-urlencoded. The flattening is detected via ModelMetadata.ContainerType on the form-bound parameter descriptions, so a minimal API body — which the schema transformer already owns — is never touched twice
    • Property keys are taken verbatim from the schema, because a flattened form field is named after the model binder (Name, not name); the validator-side match stays name-insensitive
    • An action binding more than one form parameter composes its body as an allOf of one property bag per parameter; every bag is now constrained, and each bag is paired with the parameter that owns its fields — including the parameters the action binds directly (a loose scalar, array or IFormFile), which get a bag of their own but no rules. Without that pairing a DTO could be pulled into a foreign bag by a single coinciding field name and lose the constraints on its own bag
    • encoding.contentType (Issue #216) is now also emitted when the file part sits inside such an allOf bag
    • Dotted keys (Inner.City, ApiExplorer's binding path for a nested complex property) are skipped: the name matcher ignores separators, so such a key would otherwise inherit the rules of an unrelated root property named InnerCity. Nested form fields remain unsupported, matching the Swashbuckle form path
    • Issue #216 encoding.contentType is unchanged for the shapes it already covered, and now also consults every validator in multi-validator mode (IsOneValidatorForType = false) instead of only the first
    • Known limitations on this path (unchanged by this fix): a renamed form field ([FromForm(Name = "...")], or a property renamed by the INameResolver) gets no constraints, and on net10 a form part rendered as a $ref (IFormFile, enums) cannot receive property-level constraints
    • Thanks to @bux for the report

Changes in 7.2.1

  • Fixed: the document-filter pipeline (UseDocumentFilter = true) did not apply FluentValidation constraints to aliased operation parameters such as [FromHeader(Name = "X-Correlation-Id")] (Issue #230). The constraint copy now uses the resolved schema property key (kebab-case/camelCase/PascalCase aliases) and falls back to the INameResolver for renames beyond separators (e.g. [JsonPropertyName]) — full parity with the operation filter
  • Fixed: a dot in a header name ([FromHeader(Name = "X.Trace.Id")] — legal in HTTP) was treated as a nested [FromQuery] dot-path (#209/#211) and silently dropped the header's validation rules. Header-bound parameters are now exempt from the dot-path logic in all three parameter pipelines: FluentValidationOperationFilter, FluentValidationDocumentFilter and the ASP.NET Core FluentValidationOperationTransformer. NSwag is unaffected (it has no dot-path parameter logic)
  • Fixed: the document filter matched document parameters to ApiExplorer descriptions case-sensitively, so options like DescribeAllParametersInCamelCase made it skip required-marking and constraint copying. The lookup is now case-insensitive, matching the operation filter
  • Thanks to @jgarciadelanoceda for the report and the repro

Changes in 7.2.0

  • Added: the document-filter pipeline is promoted from experimental to a supported opt-in (RegistrationOptions.UseDocumentFilter, default false). The document filter processes the whole document at once and performs the unused-query-schema cleanup once at the end, so per-operation shared-DTO state issues (#223/#226) cannot occur in this pipeline — on all target frameworks, including net8.0/net9.0 where the 7.1.11 healing API is unavailable
    • Full functional parity with the default schema + operation filter pipeline: required-marking with the whole-dot-path check (#209), request bodies and encoding.contentType for [FromForm] (#216), multi-validator support, allOf/oneOf/anyOf traversal, $ref preservation for unmodified properties (#198, net10.0), and every operation of a multi-verb path is now processed (previously only the first)
    • The #209 and #216 logic is extracted into internal components shared by both pipelines, so they cannot drift apart
    • Robustness: the filter no longer fails the whole document generation on a throwing validator (top-level try/catch), falls back to ServiceProviderValidatorRegistry like the sibling filters, honors an injected IFluentValidationRuleProvider (new optional constructor parameter, appended last — source-compatible), and had its dead code, logging and nullability issues cleaned up. Behavior note: constructing FluentValidationDocumentFilter with neither validatorRegistry nor serviceProvider now throws ArgumentNullException (matching the sibling filters) instead of silently producing a filter that applies no rules; the DI registration path is unaffected
    • On net10.0 the cleanup also heals Swashbuckle's reserved-ids for processed container types (SchemaRepository.ReplaceSchemaId), so custom document filters running afterwards can regenerate them
    • ExperimentalUseDocumentFilter still works as an [Obsolete] alias forwarding to UseDocumentFilter
    • The default pipeline is unchanged; a future major version may switch the default
    • samples/MinimalApi now runs on the document-filter pipeline; README documents the option and its caveats

Changes in 7.1.11

  • Fixed: a DTO shared between a flattened [FromQuery]/[AsParameters] binding and a request body ([FromBody]/[FromForm]) in the same document could lose its FluentValidation rules, and the emitted document could contain a $ref to a removed component (Issue #226). net10.0 target only
    • Root cause: the Issue #180 cleanup left the container type "reserved-but-removed" in Swashbuckle's SchemaRepository (component removed, internal reserved-id kept). The 7.1.10 fix (#223) recovered the schema for reading constraint values, but a later [FromBody]/[FromForm] operation binding the same type made Swashbuckle emit a $ref to a component that no longer exists (confirmed empirically), and rules applied on the recovered throwaway instance never reached the document
    • Fix (net10.0 / Swashbuckle 10.x): the Issue #180 cleanup now heals the repository state via SchemaRepository.ReplaceSchemaId (public API since Swashbuckle 10.1.0) before removing a side-effect schema — the reservation is cleared together with the component, so the next operation binding the same type regenerates a full component and the rules reach the real document object. SwashbuckleSchemaProvider tracks Type → schemaId for every GetSchemaForType call (including the Issue #209 ancestor walk) to make the healing possible
    • net8.0/net9.0 keep the 7.1.10 behavior: they pin Swashbuckle 8.1.1 where ReplaceSchemaId does not exist, and bumping the minimum would force the Microsoft.OpenApi 2.x breaking change on consumers. The throwaway recovery from #223 remains as a safety net on all targets
    • Thanks to @jgarciadelanoceda for suggesting the ReplaceSchemaId approach

Changes in 7.1.10

  • Fixed: the same [FromQuery]/[AsParameters] DTO shared by more than one endpoint lost its FluentValidation rules on every endpoint after the first (Issue #223)
    • FluentValidationOperationFilter runs once per operation. The Issue #180 cleanup removes the temporary container schema from SchemaRepository.Schemas, but Swashbuckle keeps the type in its internal reserved-ids map, which the cleanup does not touch. For the 2nd+ endpoint, GetSchemaForType → GenerateSchema then returns a bare $ref (no Properties) and the schema is no longer in Schemas, so the "has properties" guard was skipped and no rules were applied. Only reproduces with the default RemoveUnusedQuerySchemas = true
    • Fix: in SwashbuckleSchemaProvider.GetSchemaForType, when the returned schema has no properties and the id is absent from the shared repository (the reserved-but-removed state), the concrete schema is recovered by generating it into a throwaway SchemaRepository. Fully isolated — it never mutates the shared repository or its reserved-id state — so the Issue #180 cleanup and all other OperationFilter behavior (required marking #209, nested [FromQuery] #211/#213, request bodies, #216) are preserved

Full release notes can be found at: https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation/blob/master/CHANGELOG.md

Version Downloads Last updated
7.2.2 5 2026-10-14
7.2.1 0 2026-07-13
7.2.0 0 2026-07-12
7.1.11 0 2026-07-12
7.1.10 0 2026-07-12
7.1.9 0 2026-07-09
7.1.8 0 2026-07-01
7.1.8-beta.2 0 2026-06-21
7.1.8-beta.1 0 2026-06-20
7.1.7 0 2026-06-20
7.1.7-beta.3 0 2026-06-17
7.1.7-beta.2 0 2026-06-17
7.1.7-beta.1 0 2026-06-15
7.1.6 0 2026-06-02
7.1.6-beta.1 0 2026-06-02
7.1.5-beta.2 0 2026-05-16
7.1.5-beta 0 2026-04-01
7.1.4 63 2026-05-26
7.1.4-beta 0 2026-03-24
7.1.3 23 2026-03-26
7.1.2 0 2026-03-09
7.1.1 0 2026-03-09
7.1.0 0 2026-03-09
7.1.0-beta.2 0 2026-03-06
7.1.0-beta.1 0 2026-02-23
7.0.6 0 2026-03-03
7.0.5 0 2026-02-26
7.0.4 0 2026-02-17
7.0.4-beta.3 0 2026-02-14
7.0.4-beta.2 0 2026-02-14
7.0.4-beta.1 0 2026-02-14
7.0.3 0 2025-12-23
7.0.2 0 2025-12-23
7.0.1 0 2025-12-08
6.1.1 0 2025-09-02
6.1.0 0 2024-11-26
6.0.0 49 2025-05-06
6.0.0-beta.3 0 2023-02-19
6.0.0-beta.1 0 2022-07-23