Swashbuckle.AspNetCore icon indicating copy to clipboard operation
Swashbuckle.AspNetCore copied to clipboard

Newtonsoft UnixDateTimeConverter is not respected

Open lus opened this issue 3 years ago • 3 comments

I set up SwaggerGen with Newtonsoft support like this:

builder.Services.AddSwaggerGen(options =>
{
    string filename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, filename));
});
builder.Services.AddSwaggerGenNewtonsoftSupport();

Newtonsoft is configured like this:

builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
    options.SerializerSettings.Converters.Add(new StringEnumConverter(typeof(CamelCaseNamingStrategy)));
    options.SerializerSettings.Converters.Add(new UnixDateTimeConverter());
    options.SerializerSettings.ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new SnakeCaseNamingStrategy(),
    };
});

In the example response I see that both the SnakeCaseNamingStrategy and my custom StringEnumConverter are correctly applied, but the UnixDateTimeConverter seems to be ignored as DateTimes still get represented as strings. Am I missing something or is this a bug?

I am using Swashbuckle.AspNetCore and Swashbuckle.AspNetCore.Newtonsoft version 6.5.0.

lus avatar Feb 09 '23 10:02 lus

I managed to find a temporary workaround for my issue. I created the following schema filter that converts all date-time values to int64 ones:

public class DateTimeFilter : ISchemaFilter
{

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        foreach (KeyValuePair<string, OpenApiSchema> property in schema.Properties)
        {
            if (property.Value.Format != "date-time")
            {
                continue;
            }

            property.Value.Type = "integer";
            property.Value.Format = "int64";
            property.Value.Example = new OpenApiLong(1676290252);
        }
    }

}

I don't think this is a good permanent solution though, so I hope to find a more elegant way for that soon.

lus avatar Feb 13 '23 12:02 lus

I have been studying this issue and the issue is right. I have solved but I think that this shouldn't be supported in the library, because the solution will only work for Newtonsoft. You could see the issue dotnet/runtime#63039 for more information.

@martincostello I think that the library shouldn't support Converters that exists in Newtonsoft, and they do not in System.Text.Json. Also the solution he found was just easy. If you think the same you could close the issue although there are possibilities to support this

jgarciadelanoceda avatar Jun 02 '24 11:06 jgarciadelanoceda

I think I agree. System.Text.Json doesn't have first-class support for such functionality either, suggesting a custom converter, so we couldn't have parity.

Enums are already special-cased, but that's because they're a lot more ubiquitous(?). Also naming is a bit of a different customisation proposition, as IIRC, there's APIs to effectively query the serializer to get the name for a property, where as getting the format of how a value of a property serialized is much more difficult as you also need a value of that type to test against.

Supporting various custom converters, even if they're built in, could be a bit of a slippery slope (Newtonsoft.Json appears to have 16), so where do we draw the line? If this can be resolved by using a schema filter by the user to get the correct behaviour, then I think that's enough.

martincostello avatar Jun 02 '24 13:06 martincostello

This issue is stale because it has been open for 60 days with no activity. It will be automatically closed in 14 days if no further updates are made.

github-actions[bot] avatar Aug 04 '24 01:08 github-actions[bot]

This issue was closed because it has been inactive for 14 days since being marked as stale.

github-actions[bot] avatar Aug 19 '24 01:08 github-actions[bot]