RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.67k stars 1.23k forks source link

Error: Cannot generate swagger.json with JsonSerializerOptions property #4738

Open M0destru opened 7 months ago

M0destru commented 7 months ago

After upgrading to NET8 and NSwag version >=14 documentation cannot be generated for controller method that returns such a model:

public class ReturnModel
{
    public object? AdditionalInfo { get; set; }

    // this line doesn't allow you to generate
    protected JsonSerializerOptions JsonSerializerOptions => 
        new() { PropertyNameCaseInsensitive = true };

}

[HttpGet]
public async Task<ReturnConclusionModel> Read()
{
    return await Task.FromResult(new ReturnConclusionModel());
}

The problem arises with the line that represents JSON serialization settings for the class.

Exception:

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: This operation is only valid on generic types.
         at System.RuntimeType.GetGenericTypeDefinition()
         at Namotion.Reflection.ContextualType.<get_Fields>b__36_0(FieldInfo field)
         at System.Linq.Enumerable.SelectArrayIterator`2.Fill(ReadOnlySpan`1 source, Span`1 destination, Func`2 func)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Namotion.Reflection.ContextualType.get_Fields()
...

In version 13.20.0 it works correctly. I am attaching a fully working example. NSwagExample.zip There is a .csproj to run the version on NSwag 13.20.0 (.NET6) and also 14.0.2 (.NET8), when throws exception

R0boC0p commented 3 weeks ago

Same error for me on a model having a protected JsonSerilaizerOptions _options;. Is this being worked on? Is there any workaround for it? Why does it consider protected members in the reflection process?

My temporary solution is to set

        openApiconfig.SchemaSettings.ExcludedTypeNames = [typeof(JsonSerializerOptions).FullName];