You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #170, which was fixed only in the Swashbuckle pipeline.
Summary
With MicroElements.AspNetCore.OpenApi.FluentValidation (the native Microsoft.AspNetCore.OpenApi integration, net9.0/net10.0), FluentValidation rules are not applied to a [FromForm] DTO bound by an MVC controller action.
Expected: Name carries minLength: 1 / maxLength: 42, Age carries minimum: 7 / maximum: 99, and Name is in required.
Minimal APIs are not affected — app.MapPost("/api/upload", ([FromForm] UploadImageRequest r) => ...) emits a $ref to a component schema, so FluentValidationSchemaTransformer runs normally and the rules land (verified in the same document).
Microsoft.AspNetCore.OpenApi builds the request-body schema inline from those descriptions instead of referencing the DTO's JsonTypeInfo.
Therefore FluentValidationSchemaTransformer is never invoked for Issue170FormDto — it only sees the leaf string / int schemas.
FluentValidationOperationTransformer.ApplyRulesToRequestBody (src/MicroElements.AspNetCore.OpenApi.FluentValidation/FluentValidationOperationTransformer.cs, lines ~90-140) handles onlymultipart/form-data and only writes encoding.<part>.contentType for Issue Add support for media types #216. It never applies ordinary constraints, and application/x-www-form-urlencoded is not inspected at all.
The Swashbuckle pipeline already covers this via RequestBodyRuleApplicator (src/MicroElements.Swashbuckle.FluentValidation/Swashbuckle/RequestBodyRuleApplicator.cs), which iterates both form content types and applies the rules to the inline or $ref-ed schema.
Proposed fix
Port the RequestBodyRuleApplicator behavior into FluentValidationOperationTransformer:
resolve the DTO type from the operation's ApiDescription parameters whose BindingSource is Form,
apply the rule set to the inline request-body schema for both multipart/form-data and application/x-www-form-urlencoded,
Gotcha: in the flattened controller schema the property keys are the binding names (Name, Age — PascalCase), not the JSON-serialized names. The property lookup must match the binding name and must not assume the INameResolver / JSON naming policy output. A case-insensitive lookup with an INameResolver fallback (the shape used for #230) is probably the right approach.
Affected
MicroElements.AspNetCore.OpenApi.FluentValidation 7.2.1 (and earlier), net9.0 and net10.0
Follow-up to #170, which was fixed only in the Swashbuckle pipeline.
Summary
With
MicroElements.AspNetCore.OpenApi.FluentValidation(the nativeMicrosoft.AspNetCore.OpenApiintegration, net9.0/net10.0), FluentValidation rules are not applied to a[FromForm]DTO bound by an MVC controller action.Reported by @bux in #170 (comment) (v7.2.1). Reproduced locally.
Repro
Generated document (net10.0):
Expected:
NamecarriesminLength: 1/maxLength: 42,Agecarriesminimum: 7/maximum: 99, andNameis inrequired.Minimal APIs are not affected —
app.MapPost("/api/upload", ([FromForm] UploadImageRequest r) => ...)emits a$refto a component schema, soFluentValidationSchemaTransformerruns normally and the rules land (verified in the same document).Root cause
ApiExplorerflattens a[FromForm]complex parameter into individual form-field descriptions — the same flattening that required special handling for[FromQuery]in Required property in optional nested type in[FromQuery]parameter is wrongly marked as required #209 / Validator for nested type in[FromQuery]parameter is considered even when not used #211.Microsoft.AspNetCore.OpenApibuilds the request-body schema inline from those descriptions instead of referencing the DTO'sJsonTypeInfo.FluentValidationSchemaTransformeris never invoked forIssue170FormDto— it only sees the leafstring/intschemas.FluentValidationOperationTransformer.ApplyRulesToRequestBody(src/MicroElements.AspNetCore.OpenApi.FluentValidation/FluentValidationOperationTransformer.cs, lines ~90-140) handles onlymultipart/form-dataand only writesencoding.<part>.contentTypefor Issue Add support for media types #216. It never applies ordinary constraints, andapplication/x-www-form-urlencodedis not inspected at all.The Swashbuckle pipeline already covers this via
RequestBodyRuleApplicator(src/MicroElements.Swashbuckle.FluentValidation/Swashbuckle/RequestBodyRuleApplicator.cs), which iterates both form content types and applies the rules to the inline or$ref-ed schema.Proposed fix
Port the
RequestBodyRuleApplicatorbehavior intoFluentValidationOperationTransformer:ApiDescriptionparameters whoseBindingSourceisForm,multipart/form-dataandapplication/x-www-form-urlencoded,encoding.contentTypebehavior.Gotcha: in the flattened controller schema the property keys are the binding names (
Name,Age— PascalCase), not the JSON-serialized names. The property lookup must match the binding name and must not assume theINameResolver/ JSON naming policy output. A case-insensitive lookup with anINameResolverfallback (the shape used for #230) is probably the right approach.Affected
MicroElements.AspNetCore.OpenApi.FluentValidation7.2.1 (and earlier), net9.0 and net10.0