调用Microsoft Graph API获取SharePoint文件统计时遇JSON解析错误
问题场景
尝试通过以下代码获取SharePoint站点文件使用统计:
var report_SP_Usage_File_Counts = await graphClient.Reports.GetSharePointSiteUsageFileCounts("D180").Request().GetAsync();
执行后抛出JSON解析错误:
System.Text.Json.JsonException: 'R' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0. ---> System.Text.Json.JsonReaderException: 'R' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0. at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes) at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker) at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first) at System.Text.Json.Utf8JsonReader.ReadSingleSegment() at System.Text.Json.Utf8JsonReader.Read() at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) --- End of inner exception stack trace --- at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex) at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonReaderState& readerState, Boolean isFinalBlock, ReadOnlySpan`1 buffer, JsonSerializerOptions options, ReadStack& state, JsonConverter converterBase) at System.Text.Json.JsonSerializer.ContinueDeserialize[TValue](ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, JsonConverter converter, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.ReadAllAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken) at Microsoft.Graph.Serializer.DeserializeObject[T](Stream stream) at Microsoft.Graph.ResponseHandler.HandleResponse[T](HttpResponseMessage response) at Microsoft.Graph.BaseRequest.SendAsync[T](Object serializableObject, CancellationToken cancellationToken, HttpCompletionOption completionOption) at MinimalAPI.Endpoints.Reporting.mw_m365_GroupActivityTable_GRAPH() at Microsoft.AspNetCore.Http.RequestDelegateFactory.<ExecuteTask>g__ExecuteAwaited|58_0[T](Task`1 task, HttpContext httpContext) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
错误原因
Microsoft Graph的GetSharePointSiteUsageFileCountsAPI返回的是CSV格式数据,而非JSON。默认的Graph客户端尝试将返回内容反序列化为JSON对象,而CSV的开头字符(通常是表头的第一个字母,比如"Report Date"的'R')不符合JSON格式,因此抛出解析错误。
正确实现步骤
- 获取原始CSV内容:不使用强类型的
GetAsync(),而是直接获取HTTP响应并读取CSV字符串。 - 解析CSV数据:使用CSV解析库(如CsvHelper)将字符串转换为可操作的实体对象。
代码示例
1. 获取CSV内容
// 创建请求 var request = graphClient.Reports.GetSharePointSiteUsageFileCounts("D180").Request(); // 发送请求并获取响应 var response = await request.SendAsync(HttpCompletionOption.ResponseHeadersRead); // 读取CSV字符串 var csvContent = await response.Content.ReadAsStringAsync();
2. 解析CSV(使用CsvHelper)
首先安装CsvHelper NuGet包:Install-Package CsvHelper
然后定义对应CSV列的实体类:
using CsvHelper.Configuration.Attributes; using System.Globalization; public class SharePointSiteUsageFileCount { [Name("Report Date")] public DateTime ReportDate { get; set; } [Name("Site Type")] public string SiteType { get; set; } [Name("Total")] public long TotalFiles { get; set; } [Name("Active")] public long ActiveFiles { get; set; } }
最后解析CSV:
using var stringReader = new StringReader(csvContent); using var csvReader = new CsvHelper.CsvReader(stringReader, CultureInfo.InvariantCulture); var usageRecords = csvReader.GetRecords<SharePointSiteUsageFileCount>().ToList();
必要权限
调用该API需要Reports.Read.All权限,可配置为:
- 应用权限:适用于后台服务场景
- 委派权限:需要用户拥有全局管理员、报表阅读器等角色
内容的提问来源于stack exchange,提问作者redoc01
相关产品推荐
相关产品推荐

