#c# #asp.net-core #asp.net-web-api #swagger #swashbuckle
#c# #asp.net-core #asp.net-web-api #чванство #swashbuckle
Вопрос:
Я создаю веб-API Core 3.1 и использую JsonPatch для создания действия ИСПРАВЛЕНИЯ. У меня есть действие с именем Patch
, у которого есть JsonPatchDocument
параметр. Вот подпись действия:
[HttpPatch("{id}")]
public ActionResult<FileRecordDto> Patch(int id, [FromBody] JsonPatchDocument<FileRecordQueryParams> patchDoc)
Как я понимаю, параметр должен получать данные JSON в следующей структуре, которую я успешно протестировал с помощью действия:
[
{
"op": "operationName",
"path": "/propertyName",
"value": "newPropertyValue"
}
]
Однако документация действия, сгенерированная Swagger, имеет другую структуру:
Я не знаком с этой структурой, и в ней отсутствует даже "value"
свойство, которое есть у JsonPatchDocument
объекта. Каждый пример исправления с replace
помощью операции, которую я видел, имел первую структуру.
Почему Swagger генерирует альтернативную структуру для JsonPatchDocument
объекта в теле запроса для конечной точки ИСПРАВЛЕНИЯ? Как мне это исправить?
Комментарии:
1. Какая версия swagger? Существует несколько стандартов
2. Вот последнее изменение (версия 3.0.3) . Из вопроса неясно, что должен представлять этот JSON, поэтому трудно быть конкретным
3. Спасибо. У меня есть пакет NuGet Swashbuckle. AspNetCore v5.6.3 установлен для получения инструментов Swagger, хотя я не уверен, отделена ли его версия от Swaggers или это вообще отдельная вещь.
4. Я обновил вопрос, чтобы показать картину того, что должен представлять JSON.
5. и что
JsonPatchDocument<FileRecordQueryParams>
?
Ответ №1:
Swashbuckle.AspNetCore
не работает должным образом с этим типом JsonPatchDocument<UpdateModel>
, который не представляет ожидаемое удвоение запроса на исправление.
Вам необходимо настроить фильтр документа для изменения сгенерированной спецификации.
public class JsonPatchDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var schemas = swaggerDoc.Components.Schemas.ToList();
foreach (var item in schemas)
{
if (item.Key.StartsWith("Operation") || item.Key.StartsWith("JsonPatchDocument"))
swaggerDoc.Components.Schemas.Remove(item.Key);
}
swaggerDoc.Components.Schemas.Add("Operation", new OpenApiSchema
{
Type = "object",
Properties = new Dictionary<string, OpenApiSchema>
{
{"op", new OpenApiSchema{ Type = "string" } },
{"value", new OpenApiSchema{ Type = "string"} },
{"path", new OpenApiSchema{ Type = "string" } }
}
});
swaggerDoc.Components.Schemas.Add("JsonPatchDocument", new OpenApiSchema
{
Type = "array",
Items = new OpenApiSchema
{
Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "Operation" }
},
Description = "Array of operations to perform"
});
foreach (var path in swaggerDoc.Paths.SelectMany(p => p.Value.Operations)
.Where(p => p.Key == Microsoft.OpenApi.Models.OperationType.Patch))
{
foreach (var item in path.Value.RequestBody.Content.Where(c => c.Key != "application/json-patch json"))
path.Value.RequestBody.Content.Remove(item.Key);
var response = path.Value.RequestBody.Content.Single(c => c.Key == "application/json-patch json");
response.Value.Schema = new OpenApiSchema
{
Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "JsonPatchDocument" }
};
}
}
}
Зарегистрируйте фильтр:
services.AddSwaggerGen(c => c.DocumentFilter<JsonPatchDocumentFilter>());
Результат:
Комментарии:
1. Это сработало для меня, хотя мне нужно было добавить несколько строк, чтобы удалить неиспользуемые схемы
2. Можно ли заставить это работать, если JsonPatchDocument<T> сам находится в классе, который привязывается? Мой PatchDocument — это свойство команды dto, которое включает идентификатор из маршрута и документ из тела запроса. Этот фильтр не работает как есть.