Swashbuckle.AspNetCore.Filters throws an exception when trying to use System.Text.Json.Serialization.JsonStringEnumConverter

1

I've an ASP.NET Core 3.1 project on which I want to generate the API documentation along with queryable examples using Swagger.

I want to use the new System.Text.Json namespace instead of the good old Newtonsoft.Json one

As stated in the Swagger documentation

If you're using System.Text.Json (STJ), then the setup described above will be sufficient, and STJ options/attributes will be automatically honored by the Swagger generator

If you're using Newtonsoft, then you'll need to install a separate package and explicitly opt-in to ensure that Newtonsoft settings/attributes are automatically honored by the Swagger generator

I did NOT install the Swashbuckle.AspNetCore.Newtonsoft package and I did NOT call services.AddSwaggerGenNewtonsoftSupport().

My controller's method looks like this (I want to convert Enums to string values instead of integers)

/// <summary>
/// Just a test Method
/// </summary>
/// <param name="fooParams">My Params</param>
/// <returns></returns>
[HttpGet("Foo")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(FooResult))]
[SwaggerRequestExample(requestType: typeof(FooQuery), examplesProviderType: typeof(FooRequestExampleProvider), jsonConverter: typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
[SwaggerResponseExample(statusCode: 200, examplesProviderType: typeof(FooResponseExampleProvider), jsonConverter: typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
public FooResult Foo([FromQuery]FooQuery fooParams)
{
    return _processor.Execute<FooQuery, FooResult>(fooParams);
}

However when I execute this method (called in my Startup.cs)

public static IApplicationBuilder UseVersionedSwagger(this IApplicationBuilder app, IApiVersionDescriptionProvider provider)
{
    app.UseSwagger();

    app.UseSwaggerUI(options =>
    {
        foreach (var description in provider.ApiVersionDescriptions)
        {
            options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
        }
    });

    return app;
}

I get an exception saying

System.InvalidCastException

HResult=0x80004002

Message=Unable to cast object of type 'System.Text.Json.Serialization.JsonStringEnumConverter' to type 'Newtonsoft.Json.JsonConverter'. Source=Swashbuckle.AspNetCore.Filters

Here is the packages I reference in my .csproj

<PackageReference Include="FluentValidation.AspNetCore" Version="8.6.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="4.1.1" />
<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="3.1.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Rebus.RabbitMq" Version="5.2.0" />
<PackageReference Include="SimpleInjector.Integration.AspNetCore.Mvc" Version="4.8.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc5" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="5.0.0-rc9" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.0.0-rc5" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.0.0-rc5" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="5.0.0-rc5" />

If I change my controller's method to use Newtonsoft.Json it works well, no exception

/// <summary>
/// Just a test Method
/// </summary>
/// <param name="fooParams">My Params</param>
/// <returns></returns>
[HttpGet("Foo")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(FooResult))]
[SwaggerRequestExample(requestType: typeof(FooQuery), examplesProviderType: typeof(FooRequestExampleProvider), jsonConverter: typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
[[SwaggerResponseExample(statusCode: 200, examplesProviderType: typeof(FooResponseExampleProvider), jsonConverter: typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public FooResult Foo([FromQuery]FooQuery fooParams)
{
    return _processor.Execute<FooQuery, FooResult>(fooParams);
}

I even tried to explicitly specify this in my Startup.cs

services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());
    });

But still I'm not able to use System.Text.Json.Serialization.JsonStringEnumConverter, only Newtonsoft.Json.Converters.StringEnumConverter works.

Here is my FooQuery class which contains a FooEnum property that I want to convert to string values in Swagger

public class FooQuery
{
    public string Code { get; set; }

    public FooEnum MyFooParam { get; set; }
}

So is my code incorrect somewhere? Did I miss something?

Or is it a problem with the Swashbuckle.AspNetCore.Filters package? Is the version 5.0.0-rc9 of this package buggy and not yet compatible with System.Text.Json.Serialization.JsonStringEnumConverter?

Thanks for your answers

asp.net-core
json.net
swagger
swashbuckle
system.text.json
asked on Stack Overflow Jan 2, 2020 by Jérôme MEVEL • edited Jan 2, 2020 by Jérôme MEVEL

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0