You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter用http.MultipartRequest调用.NET 6接口返回415错误求助

问题:Flutter通过MultipartRequest上传文件时返回415 Unsupported Media Type错误

我想用Flutter的http.MultipartRequest实现带文件附件的帖子发布功能,Flutter端代码如下:

Future<String> savePost({String content = '', XFile? file}) async{
    String messageRes = '';
    try {
      final uri = Uri.parse('$urlBase/api/posts');
      Map<String, String> headers= <String,String>{
        'Authorization':'Bearer ${Global.user!.token}',
        'content-type': 'application/json; charset=UTF-8;',
        'Accept' : 'application/json',
      };

      Map<String, String> data = {
        "content": content
      };

      var request = http.MultipartRequest('POST', uri)
        ..headers.addAll(headers)
        ..fields.addAll(data);

      if(file != null){
        request.files.add(
            http.MultipartFile(
                'picture',
                File(file.path).readAsBytes().asStream(),
                File(file.path).lengthSync(),
                filename: file.name
            )
        );
      }

      var res = await request.send();
      if(res.statusCode == 200){
        messageRes = '200';
      }else{
        messageRes = '${res.statusCode} ${res.reasonPhrase}';
      }
    } catch (e) {
      messageRes = e.toString();
    }
    return messageRes;
  }

后端使用.NET 6,代码如下:

[HttpPost]
// api/posts
public async Task<IActionResult> AddPost(CreatePostDto createDto)
{}

public class CreatePostDto
{
    public string Content { get; set; }
}

Postman测试该接口一切正常,但使用上述Flutter代码调用时返回415 Unsupported Media Type错误,请问问题出在哪里?


问题原因

  • 请求头冲突:手动设置了content-type: application/json,但MultipartRequest本身会自动生成multipart/form-data类型的请求头(包含自动生成的boundary分隔符),手动覆盖后后端无法识别这种混合类型的请求,导致415错误。
  • 后端未配置文件接收:当前CreatePostDto仅包含文本字段,没有对应接收文件的参数,同时接口未明确指定从表单数据绑定参数,无法解析上传的文件。

修复步骤

Flutter端修改

移除手动设置的content-type请求头,让MultipartRequest自动处理请求类型:

Future<String> savePost({String content = '', XFile? file}) async{
    String messageRes = '';
    try {
      final uri = Uri.parse('$urlBase/api/posts');
      Map<String, String> headers= <String,String>{
        'Authorization':'Bearer ${Global.user!.token}',
        'Accept' : 'application/json',
      }; // 移除content-type设置

      Map<String, String> data = {
        "content": content
      };

      var request = http.MultipartRequest('POST', uri)
        ..headers.addAll(headers)
        ..fields.addAll(data);

      if(file != null){
        request.files.add(
            http.MultipartFile(
                'picture',
                File(file.path).readAsBytes().asStream(),
                File(file.path).lengthSync(),
                filename: file.name
            )
        );
      }

      var res = await request.send();
      if(res.statusCode == 200){
        messageRes = '200';
      }else{
        messageRes = '${res.statusCode} ${res.reasonPhrase}';
      }
    } catch (e) {
      messageRes = e.toString();
    }
    return messageRes;
  }

.NET 6后端修改

更新DTO添加文件字段,并给接口参数加上[FromForm]特性,明确从表单数据绑定参数:

[HttpPost]
// api/posts
public async Task<IActionResult> AddPost([FromForm] CreatePostDto createDto)
{
    // 可通过createDto.Picture获取上传的文件,进行后续存储等操作
    return Ok();
}

public class CreatePostDto
{
    public string Content { get; set; }
    public IFormFile Picture { get; set; } // 添加文件接收字段
}

内容的提问来源于stack exchange,提问作者NamNguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:01:07