[英]How request body parameter access by Web API using Content-Type: multipart/form-data?
[英]Specify content-type for files in multipart/form-data for Swagger
我已經用這個簽名實現了端點
[HttpPost("Test")]
public IActionResult MyTest([Required] IFormFile pdf, [Required] IFormFile image)
{
// some stuff...
return Ok();
}
這會在 swagger.json (相關部分)中生成以下條目
"content": {
"multipart/form-data": {
"schema": {
"required": [
"image",
"pdf"
],
"type": "object",
"properties": {
"pdf": {
"type": "string",
"format": "binary"
},
"image": {
"type": "string",
"format": "binary"
}
}
},
"encoding": {
"pdf": {
"style": "form"
},
"image": {
"style": "form"
}
}
}
}
但是,我還需要指定編碼,就像在規范(v3) 中一樣。 所以對於我的任務,JSON 應該是這樣的,我想......
"encoding": {
"pdf": {
"style": "form",
"contentType": "application/pdf"
},
"image": {
"style": "form",
"contentType": "image/png, image/jpeg"
}
}
但是我怎么能從代碼中做到這一點呢? 我想過SwaggerParameter 屬性,但它只包含描述和必需的標志......
我在 .NET Core 2.2 上使用 Swashbuckle.AspNetCore NuGeT 包(版本 5.0.0-rc2)。
如果您查看這一行,您將看到僅使用Style
屬性創建編碼,而未設置ContentType
。 您可以做的是通過創建自定義Attribute
手動設置它,您可以在其中定義內容類型:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,AllowMultiple = false)]
public class OpenApiEncodingContentTypeAttribute : Attribute
{
public OpenApiEncodingContentTypeAttribute(string contentType)
{
ContentType = contentType;
}
public string ContentType { get; }
}
然后在IOperationFilter
使用該Attribute
public class FormContentTypeSchemaOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var contentTypeByParameterName = context.MethodInfo.GetParameters()
.Where(p => p.IsDefined(typeof(OpenApiEncodingContentTypeAttribute), true))
.ToDictionary(p => p.Name, s => s.GetCustomAttribute<OpenApiEncodingContentTypeAttribute>().ContentType);
if (contentTypeByParameterName.Any())
{
foreach (var requestContent in operation.RequestBody.Content)
{
var encodings = requestContent.Value.Encoding;
foreach (var encoding in encodings)
{
if (contentTypeByParameterName.TryGetValue(encoding.Key, out string value))
{
encoding.Value.ContentType = value;
}
}
}
}
}
}
然后用這個Attribute
裝飾你的參數
[HttpPost("Test")]
public IActionResult MyTest([Required] [OpenApiEncodingContentType("application/pdf")] IFormFile pdf, [Required] [OpenApiEncodingContentType("image/png, image/jpeg")] IFormFile image)
{
// some stuff...
return Ok();
}
也不要忘記在AddSwaggerGen
定義您的IOperationFilter
services.AddSwaggerGen(opts =>
{
// all other stuff
opts.OperationFilter<FormContentTypeSchemaOperationFilter>();
})
這就是你得到的
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"required": [
"image",
"pdf"
],
"type": "object",
"properties": {
"pdf": {
"type": "string",
"format": "binary"
},
"image": {
"type": "string",
"format": "binary"
}
}
},
"encoding": {
"pdf": {
"contentType": "application/pdf",
"style": "form"
},
"image": {
"contentType": "image/png, image/jpeg",
"style": "form"
}
}
}
}
}
您可能可以使用額外的檢查/空檢查和其他適合您需要的東西來改進IOperationFilter
,因為這只是一個基本實現。
您還可以查看 ISchemaFilter 和以下問題:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1148
這可能會幫助您過濾操作並為相同類型 (IFormInput) 添加不同的 contentStyles。
我相信您想要實現的目標目前只能通過自定義屬性實現,但是在活動開發中存在用於增強 FormsInput 支持的活動分支,也許您可以添加功能請求。
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/commits/enhance-support-for-forms
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.