asp.net-core - swagger/swashbuckle 是否支持 multipart/mixed 和 multipart/related?
问题描述
我已经成功地为 multipart/form-data 制作了操作过滤器,并且 swagger ui 正确呈现并且能够发出多部分请求。我想对 multipart/mixed 和 multipart/related 做同样的事情,但是 swagger ui 似乎无法处理它们。它发出的请求永远不会是多部分的。我在这里错过了什么吗?或者,也许这不是 swagger/swashbuckle 支持的东西?
这是生成的 swagger json,用于 3 个不同的控制器操作,一个表单数据,一个混合和一个相关
{
"openapi": "3.0.1",
"info": {
"title": "WebAPI.Test",
"version": "1.0"
},
"paths": {
"/MultipartFilterTest/MultiPartFormData": {
"post": {
"tags": [
"MultipartFilterTest"
],
"parameters": [
{
"name": "id",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"Guid": {
"title": "This is guid",
"type": "string",
"format": "uuid"
},
"Xml": {
"title": "This is xml string",
"type": "string"
}
}
},
"encoding": {
"Xml": {
"contentType": "application/xml"
}
}
}
}
},
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
},
"application/json": {
"schema": {
"type": "string"
}
},
"text/json": {
"schema": {
"type": "string"
}
},
"application/xml": {
"schema": {
"type": "string"
}
},
"text/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/MultipartFilterTest/MultiPartFormMixed": {
"post": {
"tags": [
"MultipartFilterTest"
],
"parameters": [
{
"name": "id",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"multipart/mixed": {
"schema": {
"type": "object",
"properties": {
"Guid": {
"title": "This is guid",
"type": "string",
"format": "uuid"
},
"Xml": {
"title": "This is xml string",
"type": "string"
}
}
},
"encoding": {
"Xml": {
"contentType": "application/xml"
}
}
}
}
},
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
},
"application/json": {
"schema": {
"type": "string"
}
},
"text/json": {
"schema": {
"type": "string"
}
},
"application/xml": {
"schema": {
"type": "string"
}
},
"text/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/MultipartFilterTest/MultiPartFormRelated": {
"post": {
"tags": [
"MultipartFilterTest"
],
"parameters": [
{
"name": "id",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"multipart/related": {
"schema": {
"type": "object",
"properties": {
"Guid": {
"title": "This is guid",
"type": "string",
"format": "uuid"
},
"Xml": {
"title": "This is xml string",
"type": "string"
}
}
},
"encoding": {
"Xml": {
"contentType": "application/xml"
}
}
}
}
},
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
},
"application/json": {
"schema": {
"type": "string"
}
},
"text/json": {
"schema": {
"type": "string"
}
},
"application/xml": {
"schema": {
"type": "string"
}
},
"text/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
},
"components": { }
}
multipart/form-data 请求看起来和工作正常:
POST http://localhost:2873/MultipartFilterTest/MultiPartFormData?id=BF37E512-EC94-4636-A2FF-6F48F91D9B49 HTTP/1.1
Host: localhost:2873
Connection: keep-alive
Content-Length: 272
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
accept: text/plain
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryjUZpdMJv9LzudkjB
Origin: http://localhost:2873
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:2873/swagger/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
------WebKitFormBoundaryjUZpdMJv9LzudkjB
Content-Disposition: form-data; name="Guid"
4847ECA1-E0DE-4161-A027-B7459A84689A
------WebKitFormBoundaryjUZpdMJv9LzudkjB
Content-Disposition: form-data; name="Xml"
<x>test</x>
------WebKitFormBoundaryjUZpdMJv9LzudkjB--
但是混合和相关的请求看起来像这样(不是多部分的):
POST http://localhost:2873/MultipartFilterTest/MultiPartFormMixed?id=BF37E512-EC94-4636-A2FF-6F48F91D9B49 HTTP/1.1
Host: localhost:2873
Connection: keep-alive
Content-Length: 67
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
accept: text/plain
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36
Content-Type: multipart/mixed
Origin: http://localhost:2873
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:2873/swagger/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
{"Guid":"4847ECA1-E0DE-4161-A027-B7459A84689A","Xml":"<x>test</x>"}
我的操作过滤器看起来像这样:
public class MultipartOperationFilter : IOperationFilter
{
/// <summary>
/// Apply the filter to the operation only if it is decorated with the attribute
/// </summary>
/// <param name="operation"></param>
/// <param name="context"></param>
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
operation.RequestBody = new OpenApiRequestBody() { Required = false };
var guidSchema = context.SchemaGenerator.GenerateSchema(
typeof(Guid),
context.SchemaRepository);
guidSchema.Title = "This is guid";
var xmlSchema = context.SchemaGenerator.GenerateSchema(
typeof(string),
context.SchemaRepository);
xmlSchema.Title = "This is xml string";
operation.RequestBody.Content.Add("multipart/form-related", new OpenApiMediaType()
{
Schema = new OpenApiSchema()
{
Type = "object",
Properties = new Dictionary<string, OpenApiSchema>()
{
{"Guid",guidSchema},
{"Xml",xmlSchema);
},
}
},
Encoding["Xml"] = new OpenApiEncoding()
{
ContentType = "application/xml"
};
});
}
}
解决方案
推荐阅读
- python-3.x - 如何使用脚本的目录作为入口点
- python - 如何运行协程但不等待它?
- linux - 在 linux journalctl 中查看用户 ID
- python - 在 python 中修复 %s sql 查询
- firebase - 如何使用 Flutter 和 Firebase 将“读取”功能添加到消息传递应用程序中
- infinispan - 无法在 JBoss EAP 7.2 上使用 Infinispan 嵌入式缓存管理器
- javascript - 如果目标文件不存在,则在 Node.js 中异步重命名文件
- javascript - 如何使用 x & y 坐标提取区域中的文本
- php - Ajax 从不启动成功:使用 xhrFields 时
- javascript - 如何使用 Firebase 数据库中的特定字段检索多个数据