包装自动包装器响应的Swagger c#ProduceResponseType

包装自动包装器响应的Swagger c#ProduceResponseType,c#,swashbuckle,autowrapper,C#,Swashbuckle,Autowrapper,由于我们所有的响应都被包装在自动包装器中 告诉swagger它们是由AutoWrapper包装的最好方法是什么 而不是在每个控制器方法上添加这个 [ProducesResponseType( 200, Type = typeof( AutoWrapper<IEnumerable<WeatherForecast>> ) )] [产品响应类型(200,类型=类型(自动包装))] 您可以尽可能减少工作量,创建自己的,并将其应用于Startup.cs中的程序集 测试模型: pu

由于我们所有的响应都被包装在自动包装器中

告诉swagger它们是由AutoWrapper包装的最好方法是什么

而不是在每个控制器方法上添加这个

[ProducesResponseType( 200, Type = typeof( AutoWrapper<IEnumerable<WeatherForecast>> ) )]
[产品响应类型(200,类型=类型(自动包装))]

您可以尽可能减少工作量,创建自己的,并将其应用于Startup.cs中的程序集

测试模型:

public class MyTestModel
{
    public string SomeString { get; set; }
    public int SomeInteger { get; set; }
    public bool SomeBool { get; set; }
}
响应包装器(灵感来源于):

在《大摇大摆》中,这一点将被说明为:

然而,这种方法依赖于在控制器方法名称中建立的命名标准,以尽量减少在约定类中需要编写的代码量。可以使用来匹配后缀、前缀、任何方法名称(忽略参数)和确切名称(参数或方法必须匹配)。例如,通过在约定类中声明以下内容,可以覆盖项目中名为
Get(int-id)
的所有控制器方法:

[ProducesResponseType(200, Type = typeof(AutoWrapper<YourObject>))]
[ApiConventionNameMatch(ApiConventionNameMatchBehavior.Prefix)]
public static void Get(int id)
{
}
[产品响应类型(200,类型=类型(自动包装))]
[ApiConventionNameMatch(ApiConventionNameMatchBehavior.Prefix)]
公共静态void Get(int-id)
{
}

这个招摇过市的IOperationFilter为我实现了这个技巧,它为每个操作创建了一个自动包装器类型

public class ResponseWrapperOperationFilter : IOperationFilter
{
    public void Apply ( OpenApiOperation operation, OperationFilterContext context )
    {
        //eg. IEnumerable<WeatherForecast>
        var responseType = context.ApiDescription.SupportedResponseTypes[0].Type;

        //eg. AutoWrapper<IEnumerable<WeatherForecast>>
        var wrappedResponseType = typeof( AutoWrapperDefinition<> ).MakeGenericType( responseType );

        //new schema, TODO is to check if schema exists
        var schema = context.SchemaGenerator.GenerateSchema(
            wrappedResponseType,
            context.SchemaRepository
            );

        var openApiResponse = new OpenApiResponse
        {
            Content = new Dictionary<string, OpenApiMediaType>()
            {
                ["application/json"] = new OpenApiMediaType()
                {
                    Schema = schema
                }
            },
        };
        operation.Responses.Clear();
        operation.Responses.Add( "200", openApiResponse );
        //TODO: add Response for other status code
    }
}
公共类响应WrapperOperationFilter:IOperationFilter
{
公共无效应用(OpenApiOperation操作,OperationFilterContext上下文)
{
//我数不清
var responseType=context.apiscription.SupportedResponseType[0]。类型;
//自动包装机
var wrappedResponseType=typeof(AutoWrapperDefinition);
//新建模式,TODO是检查模式是否存在
var schema=context.SchemaGenerator.GenerateSchema(
wrappedResponseType,
context.SchemaRepository
);
var openApiResponse=新的openApiResponse
{
Content=新字典()
{
[“application/json”]=新的OpenApiMediaType()
{
模式=模式
}
},
};
operation.Responses.Clear();
operation.Responses.Add(“200”,openApiResponse);
//TODO:为其他状态代码添加响应
}
}

如果WeatherController中有几种方法,例如GetWeather1返回列表和GetWeather2返回列表,是否有一种简单的方法可以使约定更通用?@Porton我确实尝试过使其更通用,但遇到了一些问题。我想我可能有一个想法,如何使它更通用,但我将不得不体验一些。尽管如此,我认为使用
ApiConventionNameMatchBehavior.Any
应该可以为您的场景提供技巧。我相信,您会在
公共静态void GetWeather
声明中使用该名称匹配行为。我明天要回去看看我是否能把它做得更通用。不过,事实上,我相信任何名称匹配都不会起作用,因为你的案例需要的是一种泛化生成的
类型的方法。
[HttpGet]
public List<MyTestModel> GetWeather()
{
    List<MyTestModel> models = new List<MyTestModel>
    {
        new MyTestModel
        {
            SomeString = "Hello world!",
            SomeInteger = 101,
            SomeBool = true
        }
    };

    return models;
}
[assembly: ApiConventionType(typeof(MyAppConventions))]
namespace NameSpace
{
    public class Startup
    {
      //stuff...
    }
}
[ProducesResponseType(200, Type = typeof(AutoWrapper<YourObject>))]
[ApiConventionNameMatch(ApiConventionNameMatchBehavior.Prefix)]
public static void Get(int id)
{
}
public class ResponseWrapperOperationFilter : IOperationFilter
{
    public void Apply ( OpenApiOperation operation, OperationFilterContext context )
    {
        //eg. IEnumerable<WeatherForecast>
        var responseType = context.ApiDescription.SupportedResponseTypes[0].Type;

        //eg. AutoWrapper<IEnumerable<WeatherForecast>>
        var wrappedResponseType = typeof( AutoWrapperDefinition<> ).MakeGenericType( responseType );

        //new schema, TODO is to check if schema exists
        var schema = context.SchemaGenerator.GenerateSchema(
            wrappedResponseType,
            context.SchemaRepository
            );

        var openApiResponse = new OpenApiResponse
        {
            Content = new Dictionary<string, OpenApiMediaType>()
            {
                ["application/json"] = new OpenApiMediaType()
                {
                    Schema = schema
                }
            },
        };
        operation.Responses.Clear();
        operation.Responses.Add( "200", openApiResponse );
        //TODO: add Response for other status code
    }
}