Repository navigation
Fix #3153: serialize custom values in the UI ConfigObject AdditionalItems - #4132
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4132 +/- ##
==========================================
- Coverage 95.24% 95.11% -0.13%
==========================================
Files 111 111
Lines 4142 4158 +16
Branches 848 850 +2
==========================================
+ Hits 3945 3955 +10
- Misses 197 203 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
On the codecov patch check: the two uncovered lines are the The other side of the branch, the combined resolver, is what the two new tests exercise, and the AoT behaviour is unchanged from before this PR: the resolver stays source-generated only, exactly as it is on master today. Happy to restructure it if you would rather see that path covered some other way. |
There was a problem hiding this comment.
🟢 Approval recommended
The resolver fallback directly addresses the reported failure with focused regression coverage for both middlewares.
Pull request overview
Fixes #3153 by enabling serialization of complex custom UI configuration values while preserving native AOT behavior.
Changes:
- Adds reflection fallback resolvers when dynamic code is supported.
- Preserves application-provided serializer options and source-generated native AOT paths.
- Adds Swagger UI and ReDoc regression tests.
File summaries
| File | Description |
|---|---|
src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs |
Adds Swagger UI serialization fallback. |
src/Swashbuckle.AspNetCore.ReDoc/ReDocMiddleware.cs |
Adds ReDoc serialization fallback. |
test/Swashbuckle.AspNetCore.IntegrationTests/SwaggerUIIntegrationTests.cs |
Tests complex Swagger UI additional items. |
test/Swashbuckle.AspNetCore.IntegrationTests/ReDocIntegrationTests.cs |
Tests complex ReDoc additional items. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ect AdditionalItems Both middlewares serialized ConfigObject with the source-generated context alone whenever the application had not supplied its own JsonSerializerOptions, so any complex or anonymous value in the AdditionalItems extension data threw NotSupportedException at request time. When dynamic code is supported, chain a reflection-based resolver after the source-generated one. Registered types still resolve through source generation first, so the emitted config is unchanged, and on native AoT the resolver stays source-generated only.
|
Both suggestions are applied: the shortened On the codecov patch check: the two uncovered lines are the |
f7bca47 to
2d8b7b5
Compare
4220da9
into
domaindrivendev:master
|
Thanks for your contribution @RaphaelFakhri - the changes from this pull request have been published as part of version 10.3.0 📦, which is now available from NuGet.org 🚀 |
Fixes #3153.
This is not fixed by the Microsoft.OpenApi v2 move, which only changed how the OpenAPI document is serialized. The failure is in the UI config serialization and still happens on master. With
c.ConfigObject.AdditionalItems.Add("theme", new { colors = new { primary = "#086eaa" } }), exercised through the real middleware:and the identical failure from
SwaggerUIOptionsJsonContext.Both middlewares serialize
ConfigObjectwith the source-generated context alone whenever the application has not supplied its ownJsonSerializerOptions. #2890 whitelisted primitives in those contexts, butAdditionalItemsis[JsonExtensionData], so any complex value in it has no metadata and throws.When
RuntimeFeature.IsDynamicCodeSupported, the default options now chain a reflection-based resolver after the source-generated one:Registered types still resolve through source generation first, so the emitted config is byte-identical for everything that worked before, including the camelCase naming. On native AoT the resolver stays source-generated only, so AoT support is untouched. Application-supplied
JsonSerializerOptionsstill win, as they did. No public API change.Two regression tests, one per middleware, styled after the adjacent splice tests. Against master's source both fail with the exception above. With the change,
Swashbuckle.AspNetCore.IntegrationTestsis 224 passed, 0 failed on net8.0.The tradeoff worth stating:
RuntimeFeature.IsDynamicCodeSupporteddistinguishes native AoT, not trimming, so in a trimmed-but-JIT application a user's custom config type could in principle be trimmed away and serialize incompletely. That is the same exposure as the pre-6.6 behaviour this restores, and it matches the suppression pattern already used in these two files.