Как написать ISchemaFilter для проблемных деталей в ASP.NET Core 3 и Swashbuckle 5? - PullRequest
3 голосов
/ 03 ноября 2019

Я использую ASP.NET Core 3.0 с Swashbuckle 5. Я пытаюсь написать ISchemaFilter для ProblemDetails в ASP.NET Core 3.0. ProblemDetails возвращается для множества различных кодов состояния, например, 400, 401, 403, 406, 415, 500 и т. Д. Я хочу привести другой пример ProblemDetails в зависимости от кода состояния. Как мне этого добиться? Вот код, который я написал, чтобы начать, просто нужно заполнить пробел:

public class ProblemDetailsSchemaFilter : ISchemaFilter
{
    private static readonly OpenApiObject Status400ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.5.1"),
        ["title"] = new OpenApiString("Bad Request"),
        ["status"] = new OpenApiInteger(StatusCodes.Status400BadRequest),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
        ["errors"] = new OpenApiObject()
        {
            ["property1"] = new OpenApiArray()
            {
                new OpenApiString("The property field is required"),
            },
        },
    };

    private static readonly OpenApiObject Status401ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7235#section-3.1"),
        ["title"] = new OpenApiString("Unauthorized"),
        ["status"] = new OpenApiInteger(StatusCodes.Status401Unauthorized),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status403ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.5.3"),
        ["title"] = new OpenApiString("Forbidden"),
        ["status"] = new OpenApiInteger(StatusCodes.Status403Forbidden),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status404ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.5.4"),
        ["title"] = new OpenApiString("Not Found"),
        ["status"] = new OpenApiInteger(StatusCodes.Status404NotFound),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status406ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.5.6"),
        ["title"] = new OpenApiString("Not Acceptable"),
        ["status"] = new OpenApiInteger(StatusCodes.Status406NotAcceptable),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status409ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.5.8"),
        ["title"] = new OpenApiString("Conflict"),
        ["status"] = new OpenApiInteger(StatusCodes.Status409Conflict),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status415ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.5.13"),
        ["title"] = new OpenApiString("Unsupported Media Type"),
        ["status"] = new OpenApiInteger(StatusCodes.Status415UnsupportedMediaType),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status422ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc4918#section-11.2"),
        ["title"] = new OpenApiString("Unprocessable Entity"),
        ["status"] = new OpenApiInteger(StatusCodes.Status422UnprocessableEntity),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    private static readonly OpenApiObject Status500ProblemDetails = new OpenApiObject()
    {
        ["type"] = new OpenApiString("https://tools.ietf.org/html/rfc7231#section-6.6.1"),
        ["title"] = new OpenApiString("Internal Server Error"),
        ["status"] = new OpenApiInteger(StatusCodes.Status500InternalServerError),
        ["traceId"] = new OpenApiString("00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"),
    };

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.ApiModel.Type == typeof(ProblemDetails))
        {
            // TODO: Set the default and example based on the status code.
            // schema.Default = ???;
            // schema.Example = ???;
        }
    }
}

1 Ответ

1 голос
/ 05 ноября 2019

Вот простой способ, как показано ниже:

1.Модель:

public class ProblemDetails
{
    public int ID { get; set; }
    public string Description { get; set; }
}

2.ProblemDetailsSchemaFilter:

public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
    if (context.ApiModel.Type == typeof(ProblemDetails))
    {
        // TODO: Set the default and example based on the status code.
        schema.Default = new OpenApiObject
        {
            ["ID"] = new OpenApiInteger(2),
            ["Description"] = new OpenApiString("test")
        };
        schema.Example = new OpenApiObject
        {
            ["ID"] = new OpenApiInteger(1),
            ["Description"] = new OpenApiString("test test")
        };
    }
}

3.Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
        c.SchemaFilter<ProblemDetailsSchemaFilter>();
    });
}

Вы можете отобразить schema.Example в интерфейсе Swagger: enter image description here

и сгенерировать json с помощью schema.Default: enter image description here

...