ASP.NET Core 3.0 / Swashbuckle:全局限制响应内容类型
ASP.NET Core 3.0 / Swashbuckle : restrict responses content types globally
这基本上是与 相同的问题,但对于 .NET Core 3.0
默认情况下,在 .NET Core 3.0 中,您使用 services.AddControllers()
配置 Web api,然后使用 services.AddSwaggerGen()
+ app.UseSwagger()
[=18 配置带有 swashbuckle 的 swagger =]
工作正常,但是 swagger.json 包含每个操作的多个响应内容类型 (text/plain + application/json + text/json)
I know 我可以通过在我的操作中添加 [Produces]
和 [Consumes]
来限制这些响应内容类型,但我想在每个操作中避免这种情况(即我想在全球范围内这样做)
请注意,我最好使用 System.Text.Json,但如果您有一个仅适用于 Newtonsoft.JSON 的解决方案,那总比没有好 ;)
您可以创建自定义 filter for swagger
internal class AssignContentTypeFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
operation.Consumes.Clear();
operation.Consumes.Add("application/json");
operation.Produces.Clear();
operation.Produces.Add("application/json");
}
}
然后
services.AddSwaggerGen(cfg => cfg.OperationFilter<AssignContentTypeFilter>());
Swashbuckle.AspNetCore.SwaggerGen 5.0 使用 OpenApiOperation 来描述 API 操作。
using System.Collections.Generic;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
public class AssignContentTypeFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Responses.ContainsKey("200"))
{
operation.Responses.Clear();
}
var data = new OpenApiResponse
{
Description = "Ok",
Content = new Dictionary<string, OpenApiMediaType>
{
["application/json"] = new OpenApiMediaType(),
["application/xml"] = new OpenApiMediaType(),
}
};
operation.Responses.Add("200", data);
}
}
在Startup.cs
services.AddSwaggerGen(q =>
{
q.SwaggerDoc("v1", new OpenApiInfo
{
Title = "mytitle",
Version = "v1",
});
q.OperationFilter<AssignContentTypeFilter>();
});
Swashbuckle.AspNetCore.SwaggerGen 6+ 的版本。仅删除 text/plain
内容类型。在我的案例中适用于字符串结果。
internal class RemoveTextContentOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
foreach (var (_, response) in operation.Responses)
{
if (response.Content.ContainsKey("text/plain"))
response.Content.Remove("text/plain");
}
}
}
为字符串操作生成的 swagger:
"/api/news/{newsArticleId}/file-link": {
"get": {
"tags": [
"NewsApi"
],
"operationId": "NewsApi_GetUploadFileLink",
"parameters": [
{
"name": "newsArticleId",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"500": {
"description": "Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
}
}
},
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "string"
}
},
"text/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
这就是我在 Swashbuckle.AspNetCore.SwaggerGen 5.0 中工作的方式:
using System.Collections.Generic;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
internal class ContentTypeOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.RequestBody == null)
{
return;
}
operation.RequestBody.Content = new Dictionary<string, OpenApiMediaType>
{
{ "application/json", new OpenApiMediaType() }
};
foreach (var response in operation.Responses)
{
response.Value.Content = new Dictionary<string, OpenApiMediaType>
{
{ "application/json", new OpenApiMediaType() }
};
}
}
}
Startup.cs(根据 sjokkogutten 的回答修改):
services.AddSwaggerGen(q =>
{
q.SwaggerDoc("v1", new OpenApiInfo
{
Title = "mytitle",
Version = "v1",
});
q.OperationFilter<ContentTypeOperationFilter>();
});
text/plain
最终出现在生成的 swagger/openapi 规范中,因为默认情况下 API 控制器有一个 StringOutputFormatter
(来自 Microsoft.AspNetCore.Mvc.Formatters
命名空间)可用。
This MSDN 进行了详细介绍,但关键在于通过执行以下操作:
services.AddControllers(options =>
{
options.OutputFormatters.RemoveType<StringOutputFormatter>();
});
..(可能在你的 Startup/ConfigureServices 中)你删除了相关的格式化程序并且 text/plain
不再出现在生成的 swagger 文档中
注意:记得要install/importMicrosoft.AspNetCore.Mvc.Formatters
这基本上是与
默认情况下,在 .NET Core 3.0 中,您使用 services.AddControllers()
配置 Web api,然后使用 services.AddSwaggerGen()
+ app.UseSwagger()
[=18 配置带有 swashbuckle 的 swagger =]
工作正常,但是 swagger.json 包含每个操作的多个响应内容类型 (text/plain + application/json + text/json)
I know 我可以通过在我的操作中添加 [Produces]
和 [Consumes]
来限制这些响应内容类型,但我想在每个操作中避免这种情况(即我想在全球范围内这样做)
请注意,我最好使用 System.Text.Json,但如果您有一个仅适用于 Newtonsoft.JSON 的解决方案,那总比没有好 ;)
您可以创建自定义 filter for swagger
internal class AssignContentTypeFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
operation.Consumes.Clear();
operation.Consumes.Add("application/json");
operation.Produces.Clear();
operation.Produces.Add("application/json");
}
}
然后
services.AddSwaggerGen(cfg => cfg.OperationFilter<AssignContentTypeFilter>());
Swashbuckle.AspNetCore.SwaggerGen 5.0 使用 OpenApiOperation 来描述 API 操作。
using System.Collections.Generic;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
public class AssignContentTypeFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Responses.ContainsKey("200"))
{
operation.Responses.Clear();
}
var data = new OpenApiResponse
{
Description = "Ok",
Content = new Dictionary<string, OpenApiMediaType>
{
["application/json"] = new OpenApiMediaType(),
["application/xml"] = new OpenApiMediaType(),
}
};
operation.Responses.Add("200", data);
}
}
在Startup.cs
services.AddSwaggerGen(q =>
{
q.SwaggerDoc("v1", new OpenApiInfo
{
Title = "mytitle",
Version = "v1",
});
q.OperationFilter<AssignContentTypeFilter>();
});
Swashbuckle.AspNetCore.SwaggerGen 6+ 的版本。仅删除 text/plain
内容类型。在我的案例中适用于字符串结果。
internal class RemoveTextContentOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
foreach (var (_, response) in operation.Responses)
{
if (response.Content.ContainsKey("text/plain"))
response.Content.Remove("text/plain");
}
}
}
为字符串操作生成的 swagger:
"/api/news/{newsArticleId}/file-link": {
"get": {
"tags": [
"NewsApi"
],
"operationId": "NewsApi_GetUploadFileLink",
"parameters": [
{
"name": "newsArticleId",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"500": {
"description": "Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ApiError"
}
}
}
},
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "string"
}
},
"text/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
这就是我在 Swashbuckle.AspNetCore.SwaggerGen 5.0 中工作的方式:
using System.Collections.Generic;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
internal class ContentTypeOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.RequestBody == null)
{
return;
}
operation.RequestBody.Content = new Dictionary<string, OpenApiMediaType>
{
{ "application/json", new OpenApiMediaType() }
};
foreach (var response in operation.Responses)
{
response.Value.Content = new Dictionary<string, OpenApiMediaType>
{
{ "application/json", new OpenApiMediaType() }
};
}
}
}
Startup.cs(根据 sjokkogutten 的回答修改):
services.AddSwaggerGen(q =>
{
q.SwaggerDoc("v1", new OpenApiInfo
{
Title = "mytitle",
Version = "v1",
});
q.OperationFilter<ContentTypeOperationFilter>();
});
text/plain
最终出现在生成的 swagger/openapi 规范中,因为默认情况下 API 控制器有一个 StringOutputFormatter
(来自 Microsoft.AspNetCore.Mvc.Formatters
命名空间)可用。
This MSDN 进行了详细介绍,但关键在于通过执行以下操作:
services.AddControllers(options =>
{
options.OutputFormatters.RemoveType<StringOutputFormatter>();
});
..(可能在你的 Startup/ConfigureServices 中)你删除了相关的格式化程序并且 text/plain
不再出现在生成的 swagger 文档中
注意:记得要install/importMicrosoft.AspNetCore.Mvc.Formatters