Чванство неожиданное действие ИСПРАВЛЕНИЯ API документация JsonPatchDocument в теле запроса примера

#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 объекта в теле запроса для конечной точки ИСПРАВЛЕНИЯ? Как мне это исправить?

Пакет NuGet, установленный для Swagger: Swashbuckle.AspNetCore v5.6.3

Комментарии:

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, которое включает идентификатор из маршрута и документ из тела запроса. Этот фильтр не работает как есть.