FastEndpoints / FastEndpoints

A light-weight REST API development framework for ASP.NET 6 and newer.
https://fast-endpoints.com
MIT License
4.64k stars 277 forks source link

Summary does not use json converters registered with swagger or fastendpoints #473

Closed rsr-maersk closed 1 year ago

rsr-maersk commented 1 year ago

Hi. Awesome package thanks!

We have added converts to swagger and fast endpoint registration. But the "Summary" does not seam to use it for the example.

static void ConfigSerializer(JsonSerializerOptions options)
{
    options.PropertyNameCaseInsensitive = true;
    options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    options.Converters..Add(new ZonedDateTimeConverter.SystemTextJsonConverter(writeLocalTime));
    options.Converters.Add(new JsonStringEnumConverter());
    options.Converters.Add(NodaConverters.InstantConverter);
    options.Converters.Add(NodaConverters.OffsetDateTimeConverter);
    options.Converters.Add(NodaConverters.LocalDateTimeConverter);
    options.Converters.Add(NodaConverters.LocalDateConverter);
}

registration

builder.Services.SwaggerDocument(options =>
{
    options.DocumentSettings = s =>
    {
        s.Title = "SCP.Timestamp.Examples.PostgresWebApi";
        s.Version = "0.1";
    };
    options.SerializerSettings = (o) => ConfigSerializer(o);
}); //define a swagger document

App:
```c#
app.UseFastEndpoints(c =>
{
    ConfigSerializer(c.Serializer.Options);
});```

However the summary does not appear to call the converter for ZonedDateTime that is in ZonedDateTimeConverter. Any thoughts as to why?

```c#
public override void Configure()
    {
        Post("/api/transportleg/import");
        AllowAnonymous();
        Summary(s =>
        {
            s.Summary = "Example demonstrating how to ingest a date time when the client provides a timezone";
            s.ExampleRequest = new CreateTransportLegFromUiReq(new TransportLegFromUiDto()
            {
                PortOfDischargeCode = "Foo",
                PortOfLoadingCode = "Bar",
                DepartureTime = new ZonedDateTime(DateTime.UtcNow.Subtract(TimeSpan.FromDays(30)).ToInstant(),
                    DateTimeZoneProviders.Tzdb["America/New_York"]),
                ArrivalTime = new ZonedDateTime(DateTime.UtcNow.Subtract(TimeSpan.FromDays(7)).ToInstant(),
                    DateTimeZoneProviders.Tzdb["Asia/Kolkata"]),
            });
        });
    }

Looks like it is using ToString on the object and not the converters

dj-nitehawk commented 1 year ago

it seems like nswag only has support for automatically picking up the string-enum-converter from STJ. have a look here. all other custom converters from the STJ settings seems to be ignored.

as a solution, i've added the ability to add newtonsoft converters to the swagger document like so:

.SwaggerDocument(o =>
{
   o.NewtonsoftSettings = s =>
   {
       s.Converters.Add(new ZonedDateTimeConverter());
   };
});

the above is available in v5.15.0.19-beta. give it a shot and let me know if you encounter any issues. thanks for bringing this to our attention.

rsr-maersk commented 1 year ago

@dj-nitehawk awesome. thanks!!!

rsr-maersk commented 1 year ago

@dj-nitehawk no cigar with the

.SwaggerDocument(o =>
{
   o.NewtonsoftSettings = s =>
   {
       s.Converters.Add(new ZonedDateTimeConverter());
   };
});

and package v5.15.0.19-beta didn't seam to do the trick. The custom converter wasn't being picked up

dj-nitehawk commented 1 year ago

can you try the following project?

Example-Project.zip

the custom converter does get called: screen-record-1692865557

update the project and send back if you can reproduce the problem.

rsr-maersk commented 7 months ago

HI @dj-nitehawk Any update is the NSwag accepts the System.Json.Text SerializerSettings yet?

dj-nitehawk commented 7 months ago

@rsr-maersk sadly still the same. uses newtonsoft mostly. so you're gonna need to make newtonsoft versions of any custom converters.

dj-nitehawk commented 4 months ago

@rsr-maersk thought you might find this info interesting: https://discord.com/channels/933662816458645504/1255257287291834560/1255915229431332934

apparently, nswag doesn't have the ability to execute json converters when generating the swagger doc. custom converters added to the swagger doc would only get picked up by the FE swagger processor when generating examples and default values. if those code paths are not hit, custom converters are not used by nswag itself.

solution is to register something nswag calls a "type mapper". details in the discord thread.

dziedrius commented 1 month ago

@dj-nitehawk trying to open mentioned discord thread fails, so can't see suggested solution, but still, wondering if this should come as fast endpoints feature, so that people would not need to mangle through several places to set it up cleanly.

dj-nitehawk commented 1 month ago

@dziedrius i believe you need to join the discord server first before being able to see posts there. use this invite link first and then click on the above link (which is still valid).

anyhow, this behavior is documented here.

wondering if this should come as fast endpoints feature

there's a limit to what FE can offer as conveniences. unfortunately this is one of the cases we haven't figured out a nice solution which requires the user to take care of it with the suggested solution. if someone has any ideas, PRs are always welcome.