Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: AdditionalItems serialization issue still present #3153

Open
mrtristan opened this issue Nov 18, 2024 · 6 comments
Open

[Bug]: AdditionalItems serialization issue still present #3153

mrtristan opened this issue Nov 18, 2024 · 6 comments
Assignees
Labels

Comments

@mrtristan
Copy link

mrtristan commented Nov 18, 2024

Describe the bug

originally discussed in #2884
fixed with: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2890/files#diff-797869ba51539b79a9ed73d460675cc6d1c8ceab044a7383a2ebf81a34c6f7d4R12

the fix was to add a bunch of types, but the approach documented for modifying the theme is not fixed by that approach.

image

a complex anonymous object is not an understood type.

Swashbuckle.AspNetCore version

6.6+

@mrtristan mrtristan added the bug label Nov 18, 2024
@martincostello
Copy link
Collaborator

The linked issue is specific to SwaggerUI's AoT support and is unrelated to Redoc.

I'm assuming you're having an issue in an AoT application using Redoc (for which support is relatively new), but that's not clear from the issue description.

Please clarify the exact scenario you're having an issue with an ideally provide a repro as code (even better as a self-contained repo) that can be used to look into the problem.

@mrtristan
Copy link
Author

@martincostello same issue here as the original reported issue. the only additional nuance in mine is that a complex object such as the value required for theme yields the same error and is unresolved. concept has been in use for years and broke with these latest versions

@martincostello
Copy link
Collaborator

From what I can assume from your screenshots, you're seeing the same kind of issue in a completely different part of the codebase.

Please provide more detail about exactly what you're trying to do and exactly what version you used, ideally with actual code. Screenshots aren't good because there's no code that can be copy-pasted - it all has to be retyped by hand.

The more complete and detailed your issue is, the easier it is to debug and fix any issues you might be having.

@mrtristan
Copy link
Author

apologies, it seemed to me that it's just one more missing type in a common area that is at issue (with of course two different entry points). not that it's valid, i would expect that this line added to the swaggerui side would yield the same result but i've not tested that.

stack
System.NotSupportedException: Metadata for type '<>f__AnonymousType0`1[<>f__AnonymousType1`1[System.String]]' was not provided to the serializer. The serializer method used does not support reflection-based creation of serialization-related type metadata. If using source generation, ensure that all root types passed to the serializer have been indicated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_NoMetadataForType(Type type)
   at System.Text.Json.JsonSerializerOptions.GetClassFromContextOrCreate(Type type)
   at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type type)
   at System.Text.Json.WriteStackFrame.InitializeReEntry(Type type, JsonSerializerOptions options)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.DictionaryOfTKeyTValueConverter`3.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJsonExtensionData(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)

the simplest repro is adding a theme entry to AdditionalItems in a project such as Swashbuckle.AspNetCore\test\WebSites\ReDoc\Startup.cs here and trying to start the redoc website project.

app.UseReDoc(c =>
{
    c.RoutePrefix = "api-docs";
    c.ConfigObject = new ConfigObject
    {
        HideDownloadButton = true,
        HideLoading = true
    };
    // add this
    c.ConfigObject.AdditionalItems.Add("theme", new { colors = new { primary = "#086eaa" } });
});

the functionality at issue is mentioned in the readme: https://github.com/domaindrivendev/Swashbuckle.AspNetCore?tab=readme-ov-file#inject-custom-css-1

image

There is a CustomUIConfig test project for SwaggerUI but seemingly not one that exercises the same for ReDoc

@EvgeniyZ
Copy link

EvgeniyZ commented Nov 21, 2024

@mrtristan thanks for flagging this bug, I'm too facing it, I think I found a workaround for anonymous types for "theme". You can do the following:

...
var theme = new { colors = new { primary = "#086eaa" } };
c.ConfigObject.AdditionalItems.Add("theme", System.Text.Json.JsonSerializer.SerializeToDocument(theme));

The reason why it's working is because ReDocOptionsJsonContext has definition of [JsonSerializable(typeof(JsonDocument))] and it's perfectly translates later on in the html

@martincostello martincostello self-assigned this Nov 23, 2024
@martincostello
Copy link
Collaborator

Playing around with the repro, using JsonNode I can avoid the serialization exception, but then for some reason Redoc doesn't like the string value.

c.ConfigObject.AdditionalItems.Add("theme", new JsonObject { ["colors"] = new JsonObject { ["primary"] = "#086eaa" } });
redoc.standalone.js:2 r: An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#3 for more information.
    at Sr (http://localhost:5154/redoc/redoc.standalone.js:2:611266)
    at Or (http://localhost:5154/redoc/redoc.standalone.js:2:613340)
    at Br (http://localhost:5154/redoc/redoc.standalone.js:2:615966)
    at http://localhost:5154/redoc/redoc.standalone.js:2:615657
    at linesColor (http://localhost:5154/redoc/redoc.standalone.js:2:618683)
    at Object.get [as linesColor] (http://localhost:5154/redoc/redoc.standalone.js:2:625878)
    at JSON.stringify (<anonymous>)
    at http://localhost:5154/redoc/redoc.standalone.js:2:625974
    at new Pi (http://localhost:5154/redoc/redoc.standalone.js:2:625988)
    at nx (http://localhost:5154/redoc/redoc.standalone.js:1825:3524)

I'm not sure that's a Swashbuckle issue though.

For now I'd say that JsonDocument/JsonObject can be used instead of anonymous types, and then serialization will work. Alternatively, you can define your own JsonSerializationContext that knows how to serialize the additional property object you're using it, and assign it to ReDocOptions.JsonSerializerOptions.

I think the only way we can "fix" this is to add first-class configuration properties for more well-known configuration settings, such as for the colours. The drawback to that is we have to constantly chase the Redoc configuration, and I don't think that's particularly sustainable.

I'm tempted to resolve this via documentation on how to make this scenario work (i.e. using custom types with the ReDocOptions.AdditionalItems property).

It's unfortunate that this was accidentally broken due to me not realising complex objects would be used with AdditionalItems, but undoing it would break native AoT support for our Redoc package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants