英文:
List is empty for httppost in Swagger
问题
目前我正在使用Swagger测试一个HttpPost方法。我的端点上除了列表字段之外,所有其他字段都已填充。
Document.cs
public class DocumentAddRequest
{
public string Name { get; set; }
public IFormFile File { get; set; }
public List<Detail> Details { get; set; }
}
Detail.cs
public class Detail
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
我正在向Details中添加两个JSON对象,但在控制器端点内检查时,它是空的。
我可以问一下,如何使用HttpPost传递列表。需要注意的一件事是,由于我正在上传文件,我使用了FromForm。
我已经搜索过,似乎Swagger UI 存在一些问题https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1107 想知道是否有其他人已经解决了这个问题。
英文:
currently I'm testing a httppost method with swagger. All the other fields are populated for my endpoint except the list.
Document.cs
public class DocumentAddRequest
{
public string Name { get; set; }
public IFormFile File { get; set; }
public List<Detail> Details { get; set; }
}
Detail.cs
public class Detail
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
I am adding two json objects into Details but when inspecting within my controller endpoint, it's empty.
May I ask how do I get a list to be passed using httppost. One thing to note is I am using FromForm since I'm uploading a file.
I've googled and it looks like swagger UI has a bit of an issue https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1107 Wondering if anyone else has been able to go around this.
答案1
得分: 1
以下是一个工作演示,您可以参考,希望能帮助您。
- 自定义模型绑定器如下:
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 Detail
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
- 结果:
英文:
Below is a work demo, you can refer it, hope it can help.
1.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;
}
}
2.Add the model binder to the model class:
[ModelBinder(BinderType = typeof(MetadataValueModelBinder))]
public class Detail
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
3.Result:
答案2
得分: 0
以下是已翻译的内容:
你可以考虑这个建议,如果你有大量的详细数据,将多个对象输入到Swagger中可能需要一些时间。
我们可以将Detail作为JSON字符串处理,然后反序列化为"Detail"对象的列表。
例如:
[HttpPost(Name = "PostFormData1")]
public IEnumerable
{
var serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var listObject = JsonSerializer.Deserialize<List<Detail>>(request.Details, serializerOptions);
return listObject;
}
public class DocumentAddRequest
{
public string Name { get; set; }
public IFormFile File { get; set; }
public string Details { get; set; }
}
public class Detail
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
Swagger输入使用以下JSON字符串处理详细数据:
[{ "PropertyName": "test", "PropertyValue": "test2" }, { "PropertyName": "test3", "PropertyValue": "test4" }]
Swagger响应:(图片链接未翻译)
Debug:(图片链接未翻译)
英文:
You might consider this as a suggestion in case you have a ton of Detail data, inputting multiple objects into Swagger might take time.
We can take the Detail as a JSON string and then deserialize it into a list of "Detail" objects.
E.g:
[HttpPost(Name = "PostFormData1")]
public IEnumerable<Detail> PostFormData([FromForm] DocumentAddRequest request)
{
var serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var listObject = JsonSerializer.Deserialize<List<Detail>>(request.Details, serializerOptions);
return listObject;
}
public class DocumentAddRequest
{
public string Name { get; set; }
public IFormFile File { get; set; }
public string Details { get; set; }
}
public class Detail
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
Swagger Input using following JSON String for Detail data:
[{ "PropertyName": "test", "PropertyValue": "test2" }, { "PropertyName": "test3", "PropertyValue": "test4" }]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论