Импортируйте коллекцию OpenAPI 2.0 Postman и все тела запросов POST отображаются как x- www-form-urlencoded вместо raw JSON - PullRequest
1 голос
/ 25 февраля 2020

Что я использую?

. NET Framework 4.8
Почтальон Версия 7.19.1
Swashbuckle 5.6.0, пакет слепков


Проблема?

У меня большой API, использующий Swagger (Swashbuckle), и я хочу импортировать схему Open API в Postman как коллекцию.
После перехода на {myUrl}/swagger/docs/v1 и вставки схемы в Почтальон Я заметил, что все мои почтовые запросы были «сломаны». При переходе к Body оно было показано как "application/x-www-form-urlencoded", а не как необработанное JSON тело.

enter image description here

Вместо этого это выглядит так:

enter image description here

My схема:

{
    "swagger": "2.0",
    "info": {
        "version": "v1",
        "title": "My API"
    },
    "host": "localhost:51209",
    "schemes": [
        "http"
    ],
    "paths": { },
    "definitions": { }
}

paths и definitions не пустые, они содержат много вызовов API, поэтому я выберу только один метод POST, потому что все они имеют одну и ту же проблему.

Вот один пример paths объекта и свойства "consumes" в нем:

"/api/MyController/MyMethod": {
        "consumes": [
            "application/json",
            "text/json",
            "application/xml",
            "text/xml",
            "application/x-www-form-urlencoded"
        ]
}

Как кажется, проблема в свойстве объекта consumes, которое имеет массив строки в качестве значений, и одно из них "application/x-www-form-urlencoded".

У меня нет «специальных» атрибутов над моим действием или контроллером в. NET Web API.

[HttpPost]
[Route("MyMethod")]
public IHttpActionResult MyMethod(List<JobHeaderInputModel> jobHeaderList)

Я знаю, что есть Consumes атрибут для ASP Net Core, но я включен. NET Framework.

1 Ответ

1 голос
/ 26 февраля 2020

Решение:

Я видел эту удивительную статью и реализовал там решение:

Создал пользовательский атрибут:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class SwaggerConsumesAttribute : Attribute
{
    public SwaggerConsumesAttribute(params string[] contentTypes)
    {
        this.ContentTypes = contentTypes;
    }

    public IEnumerable<string> ContentTypes { get; }
}

После этого создайте класс OperationFilter для Swagger:

public class ConsumesOperationFilter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var attribute = apiDescription.GetControllerAndActionAttributes<SwaggerConsumesAttribute>().SingleOrDefault();
        if (attribute == null)
        {
            return;
        }

        operation.consumes.Clear();
        operation.consumes = attribute.ContentTypes.ToList();
    }
}

И, наконец, просто зарегистрируйте OperationFilter в SwaggerConfig.cs следующим образом:

c.OperationFilter<ConsumesOperationFilter>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...