在 multipart/form-data 中为 Swagger 指定文件的内容类型
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"
}
}
}
}
但是,我还需要指定编码,例如 the specs (v3)。所以对于我的任务,JSON 应该是这样的,我认为...
"encoding": {
"pdf": {
"style": "form",
"contentType": "application/pdf"
},
"image": {
"style": "form",
"contentType": "image/png, image/jpeg"
}
}
但是我如何从代码中做到这一点? 我考虑过 SwaggerParameter attribute,但它只包含描述和必需的标志...
我在 .NET Core 2.2 上使用 Swashbuckle.AspNetCore NuGeT 包(版本 5.0.0-rc2)。
您还可以查看 ISchemaFilter 和以下问题:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1148
这可能会帮助您过滤您的操作并为同一类型 (IFormInput) 添加不同的 contentStyles。
我相信你想要实现的目标目前只能通过自定义属性实现,但是在积极的开发中有一个用于增强 FormsInput 支持的活跃分支,也许你可以添加一个功能请求。
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/commits/enhance-support-for-forms
如果您查看 this line,您会看到仅使用 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"
}
}
}
}
}
您可能可以通过额外的 checks/null-checks 和其他适合您需要的东西来改进 IOperationFilter
,因为这只是一个基本实现。
我已经用这个签名实现了端点
[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"
}
}
}
}
但是,我还需要指定编码,例如 the specs (v3)。所以对于我的任务,JSON 应该是这样的,我认为...
"encoding": {
"pdf": {
"style": "form",
"contentType": "application/pdf"
},
"image": {
"style": "form",
"contentType": "image/png, image/jpeg"
}
}
但是我如何从代码中做到这一点? 我考虑过 SwaggerParameter attribute,但它只包含描述和必需的标志...
我在 .NET Core 2.2 上使用 Swashbuckle.AspNetCore NuGeT 包(版本 5.0.0-rc2)。
您还可以查看 ISchemaFilter 和以下问题:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1148
这可能会帮助您过滤您的操作并为同一类型 (IFormInput) 添加不同的 contentStyles。
我相信你想要实现的目标目前只能通过自定义属性实现,但是在积极的开发中有一个用于增强 FormsInput 支持的活跃分支,也许你可以添加一个功能请求。
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/commits/enhance-support-for-forms
如果您查看 this line,您会看到仅使用 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"
}
}
}
}
}
您可能可以通过额外的 checks/null-checks 和其他适合您需要的东西来改进 IOperationFilter
,因为这只是一个基本实现。