Search code examples
c#asp.net-coreswaggerswashbuckle

How to replace generic type to concrete type when generating Swagger documentation with Swashbuckle?


I have actions decorated with:

[ProducesResponseType(typeof(ValidationException<ErrorEnum>), StatusCodes.Status400BadRequest)]

I need to change the generated response to a different type. So I added an operation filter:

public class ValidationExceptionFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor cad)
        {
            var returnType = cad.MethodInfo.ReturnType;
            if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(ValidationException<>))
            {
                var schema = context.SchemaGenerator.GenerateSchema(typeof(ValidationExceptionDto), context.SchemaRepository);
                foreach (var item in operation.Responses["400"].Content)
                    item.Value.Schema = schema;
            }
        }
    }
}

But the generic type is not being replaced when generating the swagger json. What am I missing here?


Solution

  • With This Line you will get the return type of the method:

    var returnType = cad.MethodInfo.ReturnType;
    

    For example,A controller like:

    [HttpGet]
    [ProducesResponseType(400, Type = typeof(Some<WeatherForecast>))]
    [ProducesResponseType(200, Type = typeof(WeatherForecast))]
    public IEnumerable<WeatherForecast> Get()
    {   
    .......
    }
    

    You would get type of IEnumerable WeatherForecast instead of type of Some or WeatherForecast

    I tried to get the ProducesResponseTypeAttribute on the method and access the Type property :

        public class ValidationExceptionFilter : IOperationFilter    
        {        
            public void Apply(OpenApiOperation operation, OperationFilterContext context)        
            {            
            if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor cad)            
            {                
            var attrs=cad.MethodInfo.GetCustomAttributes(typeof(ProducesResponseTypeAttribute),true);                
            foreach(var attr in attrs)              
            {                   
              if((attr as ProducesResponseTypeAttribute).Type.IsGenericType&& (attr as ProducesResponseTypeAttribute).Type.GetGenericTypeDefinition()==typeof(Some<>))                    {                       
             var schema = context.SchemaGenerator.GenerateSchema(typeof(SomeDto), context.SchemaRepository);                        
            foreach (var item in operation.Responses["400"].Content)                            
            item.Value.Schema = schema;                    
            }                
          }            
         }        
       }    
     }
    

    The Response Type has been modified:

    enter image description here

    The jsonfile:

    enter image description here