Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Text.Json Field Serialization in .NET 5 not shown in Swashbuckle API Definition

Problem

I'm using ASP.NET Core with .NET 5 and am using the System.Text.Json serializer to serialize types containing fields (like System.Numerics.Vector3 (X, Y and Z are fields), although any type with fields behaves the same here).

I've verified that fields get serialized properly by calling the API over Postman, however the Swagger API Definition generated by Swashbuckle does not properly reflect this. (The definition just shows an empty type)

Repro

I've created a gist that reproduces this. It provides an HTTP Get method at /api/Test which returns an object of Type Test with a field and a property. Both are strings. Calling this API via Postman returns the correct values for both. Viewing the Swagger UI at /swagger or the definition at /swagger/v1/swagger.json only shows the property.

This behaviour applies to the examples in the Swagger UI as well, which only include the properties.

Expected behaviour

According to the docs the Swagger Generator should automatically copy the behaviour of System.Text.Json, which is explicitly configured to serialize fields (see line 47), so I'd expect the Swagger definition to include the field.

Summary

To reiterate, I use System.Text.Json to serialize a type with public fields. This works, and I'd prefer keeping it like this.

I try to use Swashbuckle to generate documentation of the API that returns these serializations. This only works for properties, but not fields.

Is there something else that needs to be explicitly configured for this to work?

like image 758
blenderfreaky Avatar asked Nov 27 '20 10:11

blenderfreaky


People also ask

How do I deserialize text JSON?

A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.

What is serializing and deserializing JSON in C#?

Json structure is made up with {}, [], comma, colon and double quotation marks and it includes the following data types: Object, Number, Boolean, String, and Array. Serialize means convert an object instance to an XML document. Deserialize means convert an XML document into an object instance.


1 Answers

It seems like Swashbuckle doesn't use the JsonSerializerOptions to generate the docs. One workaround i found is to handle the types manually:

public class FieldsSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        var fields = context.Type.GetFields();

        if (fields == null) return;
        if (fields.Length == 0) return;

        foreach (var field in fields)
        {
            schema.Properties[field.Name] = new OpenApiSchema
            {
                // this should be mapped to an OpenApiSchema type
                Type = field.FieldType.Name
            };
        }
    }
}

Then in your Startup.cs ConfigureServices:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication1", Version = "v1" });
    c.SchemaFilter<FieldsSchemaFilter>();
});

When stepping through, you'll see the JsonSerializerOptions used in the SchemaFilterContext (SchemaGenerator). IncludeFields is set to true. Still only properties are used for docs, so I guess a filter like that is your best bet.

like image 162
Markus Dresch Avatar answered Oct 05 '22 05:10

Markus Dresch