Flutter项目:如何通过Microsoft Graph API上传会话传递二进制数据上传邮件附件
嘿,我来帮你解决Flutter里向Microsoft Graph上传二进制附件的问题!根据你提供的Graph API要求,咱们可以用Flutter常用的网络请求库来实现,直接传递二进制字节数组就行,下面给你详细的示例:
在Flutter中向Microsoft Graph上传二进制附件(大文件分段上传)
首先要明确核心:Graph API要求的二进制数据,在Flutter里可以通过读取文件的指定字节段,转换成Uint8List后直接作为请求体传递即可。下面分两种常用库来演示:
方法一:用官方http包实现
先确保你的pubspec.yaml里添加了http依赖:
dependencies: http: ^1.1.0
示例代码
import 'dart:io'; import 'package:http/http.dart' as http; Future<void> uploadAttachmentSegment(String sessionUrl, File file, int startByte, int endByte, int totalFileSize) async { // 读取文件的指定字节段(注意endByte要+1,因为openRead的结束索引是开区间) final fileByteChunks = await file.openRead(startByte, endByte + 1).toList(); final binaryData = Uint8List.fromList(fileByteChunks.expand((chunk) => chunk).toList()); // 构造符合要求的请求头 final requestHeaders = { 'Content-Type': 'application/octet-stream', 'Content-Length': binaryData.length.toString(), 'Content-Range': 'bytes $startByte-$endByte/$totalFileSize', }; // 发起PUT请求,直接把二进制数据作为body传入 final response = await http.put( Uri.parse(sessionUrl), headers: requestHeaders, body: binaryData, ); if (response.statusCode == 200 || response.statusCode == 201) { print('当前分段上传成功!'); } else { print('上传失败,状态码:${response.statusCode},响应内容:${response.body}'); } } // 调用示例:上传第一个2MB分段 void main() async { final targetFile = File('/your/file/path/attachment.pdf'); final totalFileSize = await targetFile.length(); const segmentStart = 0; const segmentEnd = 2097151; // 对应2MB的分段大小,符合Graph建议 final uploadSessionUrl = 'https://outlook.office.com/api/beta/Users(\'a8e8e219-4931-95c1-b73d-62626fd79c32@72aa88bf-76f0-494f-91ab-2d7cd730db47\')/Messages(\'AAMkADI5MAAIT3drCAAA=\')/AttachmentSessions(\'AAMkADI5MAAIT3k0tAAA=\')?authtoken=eyJhbGciOiJSUzI1NiIsImtpZCI6IktmYUNIUlN6bllHMmNI'; await uploadAttachmentSegment(uploadSessionUrl, targetFile, segmentStart, segmentEnd, totalFileSize); }
方法二:用dio包实现(支持进度监听)
如果你的项目用dio(很多开发者偏好它的丰富功能),先添加依赖:
dependencies: dio: ^5.4.0+1
示例代码
import 'dart:io'; import 'package:dio/dio.dart'; Future<void> uploadAttachmentWithDio(String sessionUrl, File file, int startByte, int endByte, int totalFileSize) async { final dio = Dio(); // 读取指定字节段的二进制数据 final fileByteChunks = await file.openRead(startByte, endByte + 1).toList(); final binaryData = Uint8List.fromList(fileByteChunks.expand((chunk) => chunk).toList()); try { final response = await dio.put( sessionUrl, data: binaryData, // 直接传入二进制数据 options: Options( headers: { 'Content-Type': 'application/octet-stream', 'Content-Length': binaryData.length.toString(), 'Content-Range': 'bytes $startByte-$endByte/$totalFileSize', }, ), onSendProgress: (sentBytes, totalBytesInSegment) { print('当前分段上传进度:${(sentBytes / totalBytesInSegment * 100).toStringAsFixed(2)}%'); }, ); if (response.statusCode == 200 || response.statusCode == 201) { print('当前分段上传成功!'); } } on DioException catch (e) { print('上传失败:${e.message},响应内容:${e.response?.data}'); } } // 调用示例 void main() async { final targetFile = File('/your/file/path/attachment.pdf'); final totalFileSize = await targetFile.length(); const segmentStart = 0; const segmentEnd = 2097151; final uploadSessionUrl = 'https://outlook.office.com/api/beta/Users(\'a8e8e219-4931-95c1-b73d-62626fd79c32@72aa88bf-76f0-494f-91ab-2d7cd730db47\')/Messages(\'AAMkADI5MAAIT3drCAAA=\')/AttachmentSessions(\'AAMkADI5MAAIT3k0tAAA=\')?authtoken=eyJhbGciOiJSUzI1NiIsImtpZCI6IktmYUNIUlN6bllHMmNI'; await uploadAttachmentWithDio(uploadSessionUrl, targetFile, segmentStart, segmentEnd, totalFileSize); }
几个关键注意点
- Content-Range格式:必须严格遵循
bytes start-end/total的规则,start和end是当前分段的首尾字节索引(从0开始),total是文件的总字节数。 - 分段大小:Microsoft Graph建议每个分段为2MB(2097152字节),避免因请求过大导致失败。
- 权限与Token:确保你的
authtoken有效,且拥有Mail.ReadWrite这类足够的权限。
内容的提问来源于stack exchange,提问作者Jigar
相关产品推荐
相关产品推荐

