如何用C#调用Synology Calendar API创建事件?遇9007错误求解决
问题背景
我正在开发Synology Calendar API的C#客户端,基于群晖官方API文档实现。目前已完成登录、登出、获取API信息、列出所有日历、获取指定日历时间范围事件、更新事件等功能,但创建事件操作始终失败。
使用的GET请求如下({{baseUrl}}为群晖设备地址,如http://192.168.2.205:5000):
GET {{baseUrl}}/webapi/entry.cgi?api=SYNO.Cal.Event&version=1&method=create&cal_id=test&description=Test2&dtstart=TZID%3dEurope%2fBerlin%3a20231003T210000&dtend=TZID%3dEurope%2fBerlin%3a20231003T230000&is_all_day=false&is_repeat_evt=false&evt_location=Test3&original_cal_id=test2&summary=Test4&transp=TRANSPARENT&tzid=Europe%2fBerlin
请求仅携带登录获取的X-SYNO-TOKEN自定义头,返回未成功结果及错误码9007,该错误码未在官方API文档中记载。已尝试减少请求参数、改用POST请求(返回“不支持”提示)、查阅群晖论坛等操作,但均无效。
另外发现API几个未在文档中说明的特殊点:
- 布尔值必须为小写(如
false,不能用False或FALSE) - 所有操作(包括更新事件)均需使用GET请求(文档示例存在误用POST的错误)
- 文档存在不完整或错误内容
排查与解决思路
1. 移除不必要的original_cal_id参数
original_cal_id通常用于移动已有事件到其他日历的场景,创建新事件时完全不需要这个参数。你的请求中同时传入cal_id=test和original_cal_id=test2,可能导致API误判操作类型,触发未文档化的9007错误。建议直接删除该参数后重试。
2. 验证cal_id的真实性
群晖日历的cal_id一般是系统生成的数字或特定标识,不是自定义的字符串。先调用SYNO.Cal.Calendar的list接口获取所有真实存在的日历ID,替换请求中的cal_id=test为真实ID再测试。
3. 简化时间参数并检查格式
虽然你已经做了URL编码,但可以尝试简化时间相关参数:
- 确认
dtstart和dtend的时区格式完全符合要求,比如TZID=Europe/Berlin:20231003T210000编码后是否正确 - 移除重复的
tzid参数,因为dtstart和dtend已经包含了时区信息,重复传入可能引发冲突
4. 检查权限与令牌有效性
虽然其他操作正常,但创建事件可能需要额外权限。可以调用SYNO.API.Info的query接口,确认SYNO.Cal.Event的create方法所需的权限,确保当前账号拥有该权限。同时确认X-SYNO-TOKEN未过期(令牌一般有有效期,可查看登录接口的返回值确认)。
5. 捕获完整错误响应
除了错误码9007,务必获取API返回的完整错误信息(通常在error字段下的message或details中),这能提供更具体的失败原因,比如参数无效、权限不足等。
6. 用最简请求测试
先只保留必填参数发起请求,确认最简请求是否成功,再逐步添加其他参数,定位触发错误的具体项。示例最简请求:
GET {{baseUrl}}/webapi/entry.cgi?api=SYNO.Cal.Event&version=1&method=create&cal_id=真实日历ID&summary=Test&dtstart=TZID%3DEurope%2FBerlin%3A20231003T210000&dtend=TZID%3DEurope%2FBerlin%3A20231003T230000&is_all_day=false
内容的提问来源于stack exchange,提问作者FranzHuber23

