asp.net-coreswaggerswashbuckle.aspnetcore

How to show description in Swagger of an IFormFile


Unfortunately I cannot add any description to Swagger when using an IFormFile:

[Route("service")]
public class WebServiceController : Controller
{
   /// <summary>
   /// An upload
   /// </summary>
   /// <param name="file">The file to be uploaded</param>
   /// <response code="200">File uploaded</response>
   [HttpPost("upload")]
   public IActionResult Upload(IFormFile file)
   {
      ...
   }
}

In Startup.cs I also added the xml comments for swagger:

...
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = $"WebService API V1 ({GetType().Assembly.GetName().Version})", Version = "v1" });

    // Set the comments path for the Swagger JSON and UI.
    var xmlFile = $"{typeof(Startup).Assembly.GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);
});

Description is missing

Unfortunately the description is not shown in UI or can be found in the swagger.json. Has anyone an idea how to get the description used?

Thanks to bugrakosen for his answer. I extended his filter to be able to get use of the DescriptionAttribute.

...
[HttpPost("upload")]
public IActionResult Upload([Description("My description")] IFormFile file)
{
   ...
}

The updated OperationFilter

internal class SwaggerFileOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var fileUploadMime = "multipart/form-data";

        if (operation.RequestBody == null ||
            !operation.RequestBody.Content.Any(x =>
                x.Key.Equals(fileUploadMime, StringComparison.InvariantCultureIgnoreCase)))
        {
            return;
        }

        var methodParameters = context.MethodInfo.GetParameters();

        foreach (var schemaProperty in operation.RequestBody.Content[fileUploadMime].Schema.Properties)
        {
            var descriptionAttr = methodParameters.FirstOrDefault(param => param.Name == schemaProperty.Key)?
                                                    .GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault() as DescriptionAttribute;
            if (descriptionAttr != null)
            {
                schemaProperty.Value.Description = descriptionAttr.Description;
            }
        }
    }
}

Solution

  • I'm doing file uploads via swagger with operation filter;

    Create a class named SwaggerFileOperationFilter;

    public class SwaggerFileOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var fileUploadMime = "multipart/form-data";
    
            if (operation.RequestBody == null || !operation.RequestBody.Content.Any(x => x.Key.Equals(fileUploadMime, StringComparison.InvariantCultureIgnoreCase)))
                return;
    
            var fileParams = context.MethodInfo.GetParameters().Where(p => p.ParameterType == typeof(IFormFile));
    
            operation.RequestBody.Content[fileUploadMime].Schema.Properties = fileParams.ToDictionary(k => k.Name, v => new OpenApiSchema()
            {
                Type = "string",
                Format = "binary",
                Description = "some description to be show" // --> this line
            });
        }
    }
    

    Important line for description is; Description = "some description to be show"


    In Startup.cs you should also add this line:

    ...
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = $"WebService API V1 ({GetType().Assembly.GetName().Version})", Version = "v1" });
    
        // Set the comments path for the Swagger JSON and UI.
        var xmlFile = $"{typeof(Startup).Assembly.GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        c.IncludeXmlComments(xmlPath);
    
        c.OperationFilter<SwaggerFileOperationFilter>(); // --> this line
    });
    

    Here is result;

    result

    Hope it helps!