Microsoft Graph SDK C# Newtonsoft.Json:从 JsonReader 读取 JObject 时出错

Microsoft Graph SDK C# Newtonsoft.Json: Error reading JObject from JsonReader

我想获取组的直接用户成员资格的计数。 这可以通过 Advanced Queries 来实现。我正在使用 Microsoft Graph SDK 和此代码来请求它:

var url = client
  .Groups[groupId]
  .Members
  .AppendSegmentToRequestUrl("microsoft.graph.user/$count");

var requestbuilder = new GroupRequestBuilder(url, client);

var result = await requestbuilder
  .Request()
  .Header("ConsistencyLevel", "eventual")
  .GetAsync();

应该相当于这个URL:

https://graph.microsoft.com/v1.0/groups/<groupId>/members/microsoft.graph.user/$count

与 header:

ConsistencyLevel = eventual

请求似乎没有问题,但响应仅包含纯文本形式的计数。我认为这就是 JsonReader 抛出错误的原因。 那么如何才能只得到这个纯文本结果值呢?

我尝试将 select 添加到查询中以跳过 JsonReader,但 lambda 只接受组属性...

await requestbuilder
  .Request()
  .Header("ConsistencyLevel", "eventual")
  .Select(x => new { x })
  .GetAsync();

我通过查阅 Microsoft.Graph.Core 源代码和文档弄明白了。 在我的案例中,响应消息总是反序列化导致问题的原因。

我为 text/plain 响应消息创建了自定义 IResponseHandler

    public class GraphPlainTextResponseHandler : IResponseHandler
    {
        public async Task<T> HandleResponse<T>(HttpResponseMessage response)
        {
            //Throw error if reponse is not successful
            if (!response.IsSuccessStatusCode) throw new HttpResponseException(response.StatusCode);
            //Throw error if response content-type is not of type text/plain
            if (response.Content.Headers.ContentType.MediaType != "text/plain") throw new InvalidOperationException($"Incorrect Content-Type: {response.Content.Headers.ContentType.MediaType}");

            return (T)Convert.ChangeType(await response.Content.ReadAsStringAsync(), typeof(T));

        }
    }

然后我用这个代码创建了请求:

var url = client.Groups[groupId].Members.AppendSegmentToRequestUrl("microsoft.graph.user/$count");
            var baseRequest = new BaseRequest(url, client).WithResponseHandler(new GraphPlainTextResponseHandler());
            baseRequest.Header("ConsistencyLevel", "eventual");
            
            var result = await baseRequest.SendAsync<string>(null, CancellationToken.None);