Describe the bug
Running into an issue creating a file upload endpoint with file validation middleware. If both the endpoint and middleware have an IFormFile parameter the code generation fails with the following error.
CS0128: A local variable or function named 'file' is already defined in this scope
To Reproduce
From a simple web api project I have the following endpoint and middleware classes:
public static class FileUploadEndpoint
{
[Middleware(
typeof(FileLengthValidationMiddleware),
typeof(FileExtensionValidationMiddleware)
)]
[WolverinePost("/api/files/upload")]
public static async Task<Ok> HandleAsync(IFormFile file)
{
// todo, generate filename, write mapping to table
// todo, create sideeffect to write file with new filename
return TypedResults.Ok(); // return new filename
}
}
public static class FileLengthValidationMiddleware
{
public static void Before(IFormFile file, IOptions<FileUploadOptions> options)
{
// todo, return ProblemDetail if validation fails
}
}
public static class FileExtensionValidationMiddleware
{
public static void Before(IFormFile file, IOptions<FileUploadOptions> options)
{
// todo, return ProblemDetail if validation fails
}
}
Just in case its relavent, this is my wolverine configuration (nothing special):
Expected behavior
Be able to use the IFormFile request parameter in both middleware leading up to and in the endpoint.
Additional context
For the above repro classes this is the code that is generated (seeing it returned with a 500 when the error is thrown):
// START: POST_api_files_upload
public class POST_api_files_upload : Wolverine.Http.HttpHandler
{
private readonly Wolverine.Http.WolverineHttpOptions _wolverineHttpOptions;
private readonly Microsoft.Extensions.Options.IOptions<FileUpload.Server.FileUploadOptions> _options;
public POST_api_files_upload(Wolverine.Http.WolverineHttpOptions wolverineHttpOptions, Microsoft.Extensions.Options.IOptions<FileUpload.Server.FileUploadOptions> options) : base(wolverineHttpOptions)
{
_wolverineHttpOptions = wolverineHttpOptions;
_options = options;
}
public override async System.Threading.Tasks.Task Handle(Microsoft.AspNetCore.Http.HttpContext httpContext)
{
// Retrieve header value from the request
var file = ReadSingleFormFileValue(httpContext);
FileUpload.Server.Endpoints.FileLengthValidationMiddleware.Before(file, _options);
FileUpload.Server.Endpoints.FileExtensionValidationMiddleware.Before(file, _options);
// Retrieve header value from the request
var file = ReadSingleFormFileValue(httpContext);
// Retrieve header value from the request
var file = ReadSingleFormFileValue(httpContext);
// The actual HTTP request handler execution
var ok = await FileUpload.Server.Endpoints.FileUploadEndpoint.HandleAsync(file).ConfigureAwait(false);
await ok.ExecuteAsync(httpContext).ConfigureAwait(false);
}
}
// END: POST_api_files_upload
If I name each parameter in the middleware and endpoint something different (ie. file1, etc), the generated code looks like this:
// START: POST_api_files_upload
public class POST_api_files_upload : Wolverine.Http.HttpHandler
{
private readonly Wolverine.Http.WolverineHttpOptions _wolverineHttpOptions;
private readonly Microsoft.Extensions.Options.IOptions<FileUpload.Server.FileUploadOptions> _options;
public POST_api_files_upload(Wolverine.Http.WolverineHttpOptions wolverineHttpOptions, Microsoft.Extensions.Options.IOptions<FileUpload.Server.FileUploadOptions> options) : base(wolverineHttpOptions)
{
_wolverineHttpOptions = wolverineHttpOptions;
_options = options;
}
public override async System.Threading.Tasks.Task Handle(Microsoft.AspNetCore.Http.HttpContext httpContext)
{
// Retrieve header value from the request
var file2 = ReadSingleFormFileValue(httpContext);
FileUpload.Server.Endpoints.FileLengthValidationMiddleware.Before(file2, _options);
// Retrieve header value from the request
var file3 = ReadSingleFormFileValue(httpContext);
FileUpload.Server.Endpoints.FileExtensionValidationMiddleware.Before(file3, _options);
// Retrieve header value from the request
var file1 = ReadSingleFormFileValue(httpContext);
// The actual HTTP request handler execution
var ok = await FileUpload.Server.Endpoints.FileUploadEndpoint.HandleAsync(file1).ConfigureAwait(false);
await ok.ExecuteAsync(httpContext).ConfigureAwait(false);
}
}
// END: POST_api_files_upload
And with the parameter names different swagger looks like this:
@jeremydmiller noticed having a before handler with the same parameter name for an IFormFile works, but breaks the swagger generation. Made a PR to hopefully fix that.
Describe the bug Running into an issue creating a file upload endpoint with file validation middleware. If both the endpoint and middleware have an
IFormFile
parameter the code generation fails with the following error.To Reproduce From a simple web api project I have the following endpoint and middleware classes:
Just in case its relavent, this is my wolverine configuration (nothing special):
Expected behavior Be able to use the
IFormFile
request parameter in both middleware leading up to and in the endpoint.Additional context For the above repro classes this is the code that is generated (seeing it returned with a 500 when the error is thrown):
If I name each parameter in the middleware and endpoint something different (ie.
file1
, etc), the generated code looks like this:And with the parameter names different swagger looks like this: