使用Microsoft Graph API更新Excel命名区域多单元格值遇问题求助
使用Microsoft Graph SDK for .NET更新Excel多单元格区域时的异常问题
我有一个加载到Office 365中的Excel文件,可通过Microsoft Graph API访问,文件包含多个命名区域,部分为单个值,部分为单元格块。我能通过API成功更新单个值,但更新多单元格时遇到问题:
以F10:F12的3单元格区域为例,期望设置:F10=A、F11=B、F12=C。我构造了数组[ ["A"], ["B"], ["C"] ],并通过以下C#代码调用Graph API:
public static async Task<WorkbookRange> UpdateRangeArray(string strItemId, string strSheetName, string strRangeName, List<string> strRangeValues, string strSessionId) { string[][] strValueArray = new string[strRangeValues.Count][]; try { int i = 0; foreach (var val in strRangeValues) { strValueArray[i] = new string[1] { val }; i++; } } var jsonValueArray = JsonConvert.SerializeObject(strValueArray); var rangeUpdate = new Microsoft.Graph.WorkbookRange(); rangeUpdate.Values = jsonValueArray; var result = await graphClient.Users[_strUserId].Drive.Items[strItemId].Workbook.Worksheets[strSheetName] .Range(strRangeName) .Request() .Header("workbook-session-id", strSessionId) .PatchAsync(rangeUpdate).ConfigureAwait(false); return result; }
实际结果为每个单元格都填充了整个数组[ ["A"], ["B"], ["C"] ],而非对应位置的单个值。
排查过程
- UPDATE 1:改用
.Range("F10:F12")而非命名区域,结果一致。 - UPDATE 2:已在GitHub提交Issue排查是否为SDK Bug。
- UPDATE 3:通过Graph API Explorer发送PATCH请求至URL:
https://graph.microsoft.com/v1.0/me/drive/items/{item-id}/workbook/worksheets/INPUTS/range(address='F10:F12'),请求体为{"values":[["Hello"],["How"],["Are You?"]]},可成功更新。 - UPDATE 4:通过Postman及以下RestSharp代码可成功更新:
public static async Task TestUpdatePostman() { var client = new RestClient("https://graph.microsoft.com/v1.0/users/{USER-ID}/drive/items/{ITEM-ID}/workbook/worksheets/INPUTS/range(address='F10:F12')"); client.Timeout = -1; var request = new RestRequest(Method.PATCH); request.AddHeader("Authorization", "Bearer {INSERT-TOKEN}"); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\"values\":[[\"Hello\"],[\"How\"],[\"Are You?\"]]}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); Console.WriteLine(response.Content); }
问题定位与解决方案
从测试结果来看,问题并非SDK本身的Bug,而是对WorkbookRange.Values属性的赋值方式错误:
Graph SDK for .NET中的WorkbookRange.Values属性是强类型的,它的类型是object[][](二维对象数组),SDK内部会自动负责将这个数组序列化为JSON。但手动将数组序列化为JSON字符串后再赋值给Values,会导致SDK把这个字符串当作单个值处理,最终发送的请求体变成了:
{"values": "[[\"A\"],[\"B\"],[\"C\"]]"}
而不是正确的:
{"values": [["A"],["B"],["C"]]}
这就解释了为什么每个单元格都被填充了整个数组的JSON表示。修正后的代码如下:
public static async Task<WorkbookRange> UpdateRangeArray(string strItemId, string strSheetName, string strRangeName, List<string> strRangeValues, string strSessionId) { // 直接构造二维对象数组,无需手动序列化 object[][] valueArray = strRangeValues .Select(val => new object[] { val }) .ToArray(); var rangeUpdate = new Microsoft.Graph.WorkbookRange(); rangeUpdate.Values = valueArray; // 直接赋值数组,SDK自动处理序列化 var result = await graphClient.Users[_strUserId].Drive.Items[strItemId].Workbook.Worksheets[strSheetName] .Range(strRangeName) .Request() .Header("workbook-session-id", strSessionId) .PatchAsync(rangeUpdate).ConfigureAwait(false); return result; }
额外建议
如果后续遇到SDK调用与直接REST请求结果不一致的情况,可以开启SDK的日志功能,查看实际发送的请求体内容,对比手动构造的正确请求体,就能快速定位这类序列化相关的问题。
内容的提问来源于stack exchange,提问作者gotmike




