【问题标题】:How to Write ISchemaFilter for ProblemDetails in ASP.NET Core 3 & Swashbuckle 5?如何在 ASP.NET Core 3 和 Swashbuckle 5 中为 ProblemDetails 编写 ISchemaFilter?
【发布时间】:2019-11-03 14:44:59
【问题描述】:

我正在使用带有 Swashbuckle 5 的 ASP.NET Core 3.0。我正在尝试在 ASP.NET Core 3.0 中为 ProblemDetails 编写一个 ISchemaFilterProblemDetails 返回许多不同的状态代码,例如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 = ???;
        }
    }
}

【问题讨论】:

    标签: asp.net-core swagger openapi swashbuckle openapi.net


    【解决方案1】:

    这是一个简单的解决方法,如下所示:

    1.型号:

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

    2.ProblemDetailsS​​chemaFilter:

    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>();
        });
    }
    

    您可以在 Swagger UI 上显示 schema.Example

    并使用schema.Default 生成 json:

    【讨论】:

    • 这根本不能回答问题。事实上,你仍然有代码中的 TODO 这本质上是我的问题。
    • 你对 TODO 意味着什么?你能分享更多细节吗?谢谢。
    • 根据状态码,我想在模式中返回不同的示例和默认对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2019-02-15
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多