Fix ValidationsGenerator CS8785 when AddValidation is called from multiple sites#66675
Conversation
… times Agent-Logs-Url: https://github.com/dotnet/aspnetcore/sessions/3fae42b3-2f95-4903-ac81-68a84017e338 Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes the ValidationsGenerator emitting duplicate sources (triggering CS8785 and discarding output) when AddValidation() is invoked multiple times in a project, by collapsing multiple call sites into a single emission and generating multiple [InterceptsLocation] attributes on the interceptor.
Changes:
- Collect
AddValidationcall sites before combining with discovered validatable types soRegisterSourceOutputruns once. - Update the emitter to accept multiple interceptable locations and emit one interceptor method annotated for each call site.
- Add a regression test and verified snapshot covering multiple
AddValidation()invocations.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Validation/gen/ValidationsGenerator.cs | Collects all AddValidation call sites before combining with validatable types to prevent duplicate hint-name emissions. |
| src/Validation/gen/Emitters/ValidationsGenerator.Emitter.cs | Emits multiple [InterceptsLocation] attributes for a single generated interceptor when multiple call sites exist. |
| src/Validation/test/Microsoft.Extensions.Validation.GeneratorTests/ValidationsGenerator.NoOp.cs | Adds regression test validating multiple AddValidation() calls still result in request validation (HTTP 400 on invalid payload). |
| src/Validation/test/Microsoft.Extensions.Validation.GeneratorTests/snapshots/ValidationsGeneratorTests.CanGenerateWhenAddValidationCalledMultipleTimes#ValidatableInfoResolver.g.verified.cs | Updates verified generator output to include multiple interceptor attributes for multiple call sites. |
oroztocil
left a comment
There was a problem hiding this comment.
Looks good. I'll leave it up to you if you want to apply the nit suggestions for null filtering.
|
@copilot |
…ComponentModel.Primitives reference and update snapshot Agent-Logs-Url: https://github.com/dotnet/aspnetcore/sessions/20227e2b-a4e2-47de-b4c5-b3fdd1c71a61 Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
Head branch was pushed to by a user without write access
Fixed in dc82b23. The failure had two causes from the main branch merge: (1) the generator now looks up |
ValidationsGeneratorthrewCS8785and discarded all generated output wheneverAddValidation()appeared more than once in a project. The root cause:CreateSyntaxProviderreturns anIncrementalValuesProvider<T>(one item per call site), so.Combine(validatableTypes)+RegisterSourceOutputfired once per call site — each attempting toAddSource("ValidatableInfoResolver.g.cs", ...), which is illegal.Description
ValidationsGenerator.cs: Call.Collect()on theaddValidationprovider before.Combine(validatableTypes), collapsing all call sites into a singleImmutableArraysoRegisterSourceOutputfires exactly once.ValidationsGenerator.Emitter.cs: UpdateEmitto acceptImmutableArray<InterceptableLocation?>, filter nulls using.OfType<InterceptableLocation>(), bail if empty, and emit one[InterceptsLocation]attribute per call site on the single interceptor method (already declaredAllowMultiple = true).CanGenerateWhenAddValidationCalledMultipleTimes— two consecutiveAddValidation()calls still produce a singleValidatableInfoResolver.g.cswith two[InterceptsLocation]attributes, and the endpoint correctly returns HTTP 400 for invalid input.System.ComponentModel.Primitivesassembly reference toValidationsGeneratorTestBaseso the generator can resolveSystem.ComponentModel.DisplayNameAttributeduring tests (required by theDisplayNameInfosupport added in the main branch).