Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swagger UI, array of objects in multipart/form-data

enter image description here

I have a PUT query in multipart/form-data format.

I need to send an array of objects of class. The class looks like:

    public class TestObjects
    {
       public long Id { get; set; }

       public string Name { get; set; }

       public decimal MaxScore { get; set; }
    }

What should I write in this swagger field?

like image 380
Kreal Avatar asked Dec 05 '25 02:12

Kreal


1 Answers

It is a known issue on github and it seems still not be fixed(I have also tried .NET 6).

You need put data like below: enter image description here

Then custom model binder like below:

public class MetadataValueModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (values.Length == 0)
            return Task.CompletedTask;
        var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };

        var deserialized = JsonSerializer.Deserialize(values.FirstValue, bindingContext.ModelType, options);

        bindingContext.Result = ModelBindingResult.Success(deserialized);
        return Task.CompletedTask;
    }
}

Add the model binder to the model class:

[ModelBinder(BinderType = typeof(MetadataValueModelBinder))]
public class TestObjects
{
    public long Id { get; set; }

    public string Name { get; set; }

    public decimal MaxScore { get; set; }
}

You can see the schema example does not display the example, if you want to display the example you need also custom IOperationFilter:

public class CustomOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        
        if (operation.RequestBody!=null && operation.RequestBody.Content.TryGetValue("multipart/form-data", out var openApiMediaType))
        {
            var options = new JsonSerializerOptions { WriteIndented = true };
            var array = new OpenApiArray
             {
            new OpenApiString(JsonSerializer.Serialize(new TestObjects {Id = 0, Name="string",MaxScore=0}, options)),
             };

            openApiMediaType.Schema.Properties["Competences"].Example = array;
        }
    }
}

Register the IOperationFilter:

services.AddSwaggerGen(c =>
{
    c.OperationFilter<CustomOperationFilter>();
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApi5_0", Version = "v1" });
});

Another workaround is you can use [FromBody] instead of using [FromForm]:

[HttpPut]
public void Post([FromBody] List<TestObjects> Competences)
{

}

Put json data like below:

[
  {
    "id": 1,
    "name": "aa",
    "maxScore": 1
  },
  {
    "id": 2,
    "name": "bb",
    "maxScore": 2
  }
]

Result:

enter image description here

like image 109
Rena Avatar answered Dec 09 '25 14:12

Rena



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!