Flutter调用Graph API创建Teams聊天报odata.type无效400错误
问题场景
开发对接Microsoft Teams消息发送能力时,通过Postman调用Microsoft Graph API创建oneOnOne类型聊天可正常完成请求,无报错。但使用Flutter框架开发的应用发起参数完全一致的请求时(访问令牌、接口权限、传入的用户ID均与Postman测试环境完全匹配),接口返回400 BadRequest错误,错误信息为:
The provided '#microsoft.graph.aadUserConversationMember' for 'odata.type' is not valid for this operation
该问题在Android模拟器、实体Android设备上均可稳定复现,相关实现代码如下:
- 接口请求代码(Dart):
final url = Uri.https('graph.microsoft.com', "/v1.0/chats"); final body = ChatMemberDto( personId: personId, visitedPersonId: visitedPersonId) .toJsonStr(); var response = await http.post(url, headers: _headers, body: body);
- ChatMemberDto类实现:
class ChatMemberDto { String personId; String visitedPersonId; ChatMemberDto({required this.personId, required this.visitedPersonId}); String toJsonStr() { var data = { "chatType": "oneOnOne", "members": [ { "@odata.type": "#microsoft.graph.aadUserConversationMember", "roles": ["owner"], "user@odata.bind": "https://graph.microsoft.com/v1.0/users('$personId')" }, { "@odata.type": "#microsoft.graph.aadUserConversationMember", "roles": ["owner"], "user@odata.bind": "https://graph.microsoft.com/v1.0/users('$visitedPersonId')" } ] }; return jsonEncode(data); } }
问题根因
99%的场景是请求头未显式指定Content-Type: application/json:
Dart 标准http库发送字符串类型的请求体时,默认会将Content-Type设置为text/plain,Microsoft Graph API收到未声明为JSON格式的请求时,不会按照OData协议规则解析带@前缀的注解字段,会错误解析@odata.type的取值,最终抛出类型无效的报错。而Postman发送JSON请求时会自动带上正确的Content-Type请求头,因此测试时可以正常请求。
修复步骤
- 第一步:补全请求头配置,在你定义的
_headers中显式加入JSON格式声明,示例:
final Map<String, String> _headers = { // 保留原有的Authorization等已有配置 "Authorization": "Bearer $yourAccessToken", // *必须显式添加以下配置*,不要依赖http库的默认Content-Type值 "Content-Type": "application/json" };
- 第二步:如果补全请求头后仍报错,打印
jsonEncode生成的原始请求体字符串,确认@odata.type、user@odata.bind这类带@的键名没有拼写错误、没有被意外转义。正常情况下Dart的jsonEncode方法不会修改字符串类型的键名,只要构造Map时键名书写正确就不会出问题。 - 第三步:调试时可以通过抓包工具对比Flutter侧发出的请求和Postman发出的请求,确认请求头、请求体的所有字段完全一致即可。
内容的提问来源于stack exchange,提问作者MG1616
相关产品推荐
相关产品推荐

