ASP.NET Core 6.0控制器用[FromBody]接收二进制图片报415错误
ASP.NET Core 6.0 接收二进制图片POST接口415错误解决办法
问题原因
你遇到的415错误,本质是ASP.NET Core默认的输入格式化器无法处理直接绑定二进制请求体到[FromBody] Stream参数的场景。[FromBody]特性默认适配JSON/XML这类结构化数据的格式化器,而二进制图片的Content-Type(如image/jpeg)不在这些格式化器的处理范围内,所以框架会返回“不支持的媒体类型”错误。移除[FromBody]后,默认模型绑定器也不会自动将请求体绑定到Stream参数,因此问题依然存在。
解决方案
下面提供两种可行方案,既能解决415错误,又能保留Swagger接口文档的完整性:
方案1:直接使用Request.Body获取流,配置Swagger显示二进制请求体
这种方式无需修改参数签名,通过Request.Body直接读取二进制流,同时自定义Swagger过滤器让接口文档正确展示请求体类型。
步骤1:修改控制器方法
移除Stream参数,直接通过Request.Body获取图片流:
[HttpPost("image/{pv}/{articolo}"), Consumes("image/jpeg", "image/jpg", "image/png", "image/tiff", "image/tif"), SwaggerResponse(StatusCodes.Status200OK), SwaggerResponse(StatusCodes.Status400BadRequest, "nel caso in cui PV o articolo non esistono")] public async Task<IActionResult> postImage(string pv, string articolo) { // 使用Request.Body读取二进制流 using var fileStream = Request.Body; // 执行保存到磁盘的逻辑 return Ok(); }
步骤2:添加Swagger自定义过滤器
创建一个Swagger操作过滤器,用于描述该接口的二进制请求体:
public class BinaryImageRequestBodyFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { // 匹配目标控制器方法 var method = context.MethodInfo; if (method.Name == nameof(postImage) && method.DeclaringType == typeof(YourControllerName)) { operation.RequestBody = new OpenApiRequestBody { Content = new Dictionary<string, OpenApiMediaType> { ["image/jpeg"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "string", Format = "binary" } }, ["image/jpg"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "string", Format = "binary" } }, ["image/png"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "string", Format = "binary" } }, ["image/tiff"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "string", Format = "binary" } }, ["image/tif"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "string", Format = "binary" } } } }; } } }
步骤3:注册Swagger过滤器
在Program.cs中添加过滤器注册:
builder.Services.AddSwaggerGen(c => { c.OperationFilter<BinaryImageRequestBodyFilter>(); });
方案2:自定义输入格式化器,实现Stream参数绑定
通过自定义输入格式化器,让ASP.NET Core支持将二进制请求体直接绑定到Stream参数,这样可以保留原有的参数签名,Swagger也能自动识别参数。
步骤1:创建二进制输入格式化器
public class BinaryImageInputFormatter : InputFormatter { public BinaryImageInputFormatter() { // 添加支持的图片媒体类型 SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("image/jpeg")); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("image/jpg")); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("image/png")); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("image/tiff")); SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("image/tif")); } protected override bool CanReadType(Type type) { // 只处理Stream类型的参数 return type == typeof(Stream); } public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { // 将请求体流直接返回给参数 var stream = context.HttpContext.Request.Body; return await InputFormatterResult.SuccessAsync(stream); } }
步骤2:注册格式化器
在Program.cs中将自定义格式化器添加到控制器配置:
builder.Services.AddControllers(options => { // 插入到格式化器列表的最前面,优先使用 options.InputFormatters.Insert(0, new BinaryImageInputFormatter()); });
步骤3:修改控制器方法
移除[FromBody]特性,保留Stream参数即可:
[HttpPost("image/{pv}/{articolo}"), Consumes("image/jpeg", "image/jpg", "image/png", "image/tiff", "image/tif"), SwaggerResponse(StatusCodes.Status200OK), SwaggerResponse(StatusCodes.Status400BadRequest, "nel caso in cui PV o articolo non esistono")] public async Task<IActionResult> postImage(string pv, string articolo, Stream fileStream) { // 使用fileStream执行保存到磁盘的逻辑 return Ok(); }
两种方案都能解决415错误,同时保证Swagger接口文档的正确性和可读性,你可以根据自己的代码习惯选择。
内容的提问来源于stack exchange,提问作者Perry
相关产品推荐
相关产品推荐

