Swagger UI,多部分/表单数据中的对象数组

wvt8vs2t  于 2023-02-22  发布在  其他
关注(0)|答案(1)|浏览(184)

我有一个multipart/form-data格式的PUT查询。
我需要发送一个类的对象数组。这个类看起来像:

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

       public string Name { get; set; }

       public decimal MaxScore { get; set; }
    }

我该在这招摇的田野里写些什么呢?

tct7dpnv

tct7dpnv1#

这是github上的一个known issue,似乎还没有修复(我也试过.NET 6)。
你需要把数据如下:

然后自定义模型绑定如下:

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;
    }
}

将模型绑定器添加到模型类:

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

    public string Name { get; set; }

    public decimal MaxScore { get; set; }
}

可以看到schema示例没有显示示例,如果要显示示例还需要自定义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;
        }
    }
}

注册IOperationFilter

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

另一种解决方法是使用[FromBody]代替[FromForm]

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

}

如下放置json数据:

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

结果:

相关问题