One of the API’s I’m building allows you to import files to a database.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Route("api/")] | |
public class FileController : Controller | |
{ | |
private readonly IFileService _fileService; | |
public FileController(IFileService fileService) | |
{ | |
_fileService = fileService; | |
} | |
// POST api/values | |
[HttpPost("")] | |
[ProducesResponseType(StatusCodes.Status201Created)] | |
public async Task<IActionResult> Post(IFormFile file) | |
{ | |
var uploadFileModel=new UploadFileModel() | |
{ | |
FileName = file.FileName, | |
ContentType = file.ContentType, | |
Data = file.ConvertToByteArray() | |
}; | |
var fileLocation=await _fileService.UploadFile(uploadFileModel); | |
return CreatedAtAction("GetByIdAndVersion", new {id = fileLocation.Id,version=fileLocation.Version, fileName=file.FileName},null); | |
} | |
} |
To simplify testing I wanted to allow the consumers of my API to test the API directly through the Swagger UI. Problem is that out of the box Swashbuckle(the Swagger implementation for .NET) has no clue how to interprete the IFormFile.
Let’s fix that by introducing an IOperationFilter:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FileOperationFilter : IOperationFilter | |
{ | |
public void Apply(Operation operation, OperationFilterContext context) | |
{ | |
if (context.ApiDescription.ParameterDescriptions.Any(x => x.ModelMetadata.ModelType == typeof(IFormFile))) | |
{ | |
operation.Parameters.Clear(); | |
operation.Parameters.Add(new NonBodyParameter | |
{ | |
Name = "file", // must match parameter name from controller method | |
In = "formData", | |
Description = "Upload file.", | |
Required = true, | |
Type = "file" | |
}); | |
operation.Consumes.Add("application/form-data"); | |
} | |
} | |
} |
And let’s not forget to register that IOperationFilter in our Startup.cs file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddSwaggerGen(c=> | |
{ | |
c.SwaggerDoc("v1", new Info { Title = "File API", Version = "v1" }); | |
c.OperationFilter<FileOperationFilter>(); | |
}); | |
} |
Now if we run our application and browse to the swagger endpoint(/swagger), when we try to execute our Upload operation, we get a nice Import button: