Mar*_*tin 1 c# http-status-code-415 asp.net-core .net-6.0 minimal-apis
首先,这是一个有效的 POST 映射:
app.MapPost("formulary/uploadSingle/{oldSys}/{newSys}",
async (HttpRequest request, string oldSys, string newSys) =>
{
return await MapUploadSingleFileEndpoint(request, oldSys, newSys);
}).Accepts<IFormFile>("form-data")
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status400BadRequest);
Run Code Online (Sandbox Code Playgroud)
MapUploadSingleFileEndpoint 方法使用整个主体来获取文件,如下所示:
using var reader = new StreamReader(request.Body, Encoding.UTF8);
Run Code Online (Sandbox Code Playgroud)
这在 Swagger UI 中完美运行,它显示 2 个参数以及一个文件选择对话框,点击执行返回 200。然后我可以在服务器本地复制文件并随意操作它。请注意,将表单数据更改为任何其他内容都会导致 Swagger 不显示文件部分对话框。
这就是问题所在。我需要一个采用相同参数的端点,只是它需要 2 个文件才能工作。因为我正在阅读整个正文以在前面的方法中获取单个文件,所以我显然不能在这里做同样的事情。即使情况并非如此,IFormFile 类型也会生成一个仅允许单个选择的文件选择器对话框。我尝试将接受更改为IFormFileCollection或,List<IFormFile>但这不起作用,Swagger UI 上没有文件选择器。我决定尝试创建这个自定义请求模型:
public class MultipleFormularyFilesRequest
{
public string OldExternalSystemName { get; set; }
public string NewExternalSystemName { get; set; }
public IFormFile FirstFile { get; set; }
public IFormFile SecondFile { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我还添加了以下端点映射:
app.MapPost("formulary/uploadMultiple",
async (MultipleFormularyFilesRequest request) =>
{
int i = 0;
}).Accepts<MultipleFormularyFilesRequest>("multipart/form-data")
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status400BadRequest);
Run Code Online (Sandbox Code Playgroud)
这确实会导致 Swagger UI 在请求正文下有 4 个参数和 2 个文件选择器。不幸的是,当我点击执行时,我收到此 415 错误:
Microsoft.AspNetCore.Http.BadHttpRequestException: Expected a supported JSON media type but got "multipart/form-data; boundary=----WebKitFormBoundaryUzAAKF4zHMbAvtpr".
at Microsoft.AspNetCore.Http.RequestDelegateFactory.Log.UnexpectedContentType(HttpContext httpContext, String contentType, Boolean shouldThrow)
at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass46_3.<<HandleRequestBodyAndCompileRequestDelegate>b__2>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Run Code Online (Sandbox Code Playgroud)
我怎样才能让它发挥作用?
这是因为 .NET Core Minimal API 不支持 FromBody 绑定。作为替代方案,您可以自定义参数绑定。这是文档。这是一个示例代码。
public class MultipleFormularyFilesRequest
{
public string? OldExternalSystemName { get; set; }
public string? NewExternalSystemName { get; set; }
public IFormFile? FirstFile { get; set; }
public IFormFile? SecondFile { get; set; }
public static async ValueTask<MultipleFormularyFilesRequest?> BindAsync(HttpContext context,
ParameterInfo parameter)
{
var form = await context.Request.ReadFormAsync();
var firstFile = form.Files["FirstFile"];
var secondFile = form.Files["SecondFile"];
var oldExternalSystemName = form["OldExternalSystemName"];
var newExternalSystemName = form["NewExternalSystemName"];
return new MultipleFormularyFilesRequest
{
FirstFile = firstFile,
SecondFile = secondFile,
OldExternalSystemName = oldExternalSystemName,
NewExternalSystemName = newExternalSystemName
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2303 次 |
| 最近记录: |