Microsoft graph api C#graph SDK-序列化批处理请求的结果

Microsoft graph api C#graph SDK-序列化批处理请求的结果,microsoft-graph-api,microsoft-graph-sdks,Microsoft Graph Api,Microsoft Graph Sdks,我正在构建一个程序,从AAD中的多个用户获取日历信息。 我希望尽可能高效地完成这项工作,因此我开始研究Microsoft graph批处理功能。 我能够成功地执行批处理查询,但在序列化结果时遇到问题: //1. construct a Batch request var batchRequestContent = new BatchRequestContent(); var step = 1; foreach (var userEmail in userEmails) { var re

我正在构建一个程序,从AAD中的多个用户获取日历信息。 我希望尽可能高效地完成这项工作,因此我开始研究Microsoft graph批处理功能。 我能够成功地执行批处理查询,但在序列化结果时遇到问题:

//1. construct a Batch request 
var batchRequestContent = new BatchRequestContent();
var step = 1;
foreach (var userEmail in userEmails)
{
    var requestUrl = graphServiceClient
        .Users[userEmail]
        .Calendar.Events
        .Request(new List<QueryOption>
        {
            new QueryOption("startDateTime", start.ToString("o")),
            new QueryOption("endDateTime", end.ToString("o"))
        });

    var request = new HttpRequestMessage(HttpMethod.Get, requestUrl.RequestUrl);
    var requestStep = new BatchRequestStep(step.ToString(), request);
    batchRequestContent.AddBatchRequestStep(requestStep);
    step++;
}


//2. Submit request
var batchRequest = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/$batch")
{
    Content = batchRequestContent
};
await graphServiceClient.AuthenticationProvider.AuthenticateRequestAsync(batchRequest);
var httpClient = new HttpClient();
var batchResponse = await httpClient.SendAsync(batchRequest);
//3. Process response
var batchResponseContent = new BatchResponseContent(batchResponse);
var responses = await batchResponseContent.GetResponsesAsync();
var responseHandler = new ResponseHandler(graphServiceClient.HttpProvider.Serializer);
foreach (var response in responses)
{
    if (response.Value.IsSuccessStatusCode)
    {

        var responsestring = await response.Value.Content.ReadAsStringAsync();

        var responseEvent = //?
    }
}
似乎@odata.context是错误的原因,请参见下图了解我从上述请求中得到的实际响应:


由于在提供的示例中,每个查询的响应都是预期的,因此下面的示例演示了如何对其进行反序列化:

//...
var batchResponseContent = new BatchResponseContent(batchResponse);
var responses = await batchResponseContent.GetResponsesAsync();
foreach (var response in responses)
{
    if (response.Value.IsSuccessStatusCode)
    {
        var content = await response.Value.Content.ReadAsStringAsync();
        var events = JsonConvert.DeserializeObject<List<Microsoft.Graph.Event>>(JObject.Parse(content)["value"].ToString());
        //...

    }
}   
/。。。
var batchResponseContent=新的batchResponseContent(batchResponse);
var responses=等待batchResponseContent.GetResponseAsync();
foreach(响应中的var响应)
{
if(响应.值.IsSuccessStatusCode)
{
var content=await response.Value.content.ReadAsStringAsync();
var events=JsonConvert.DeserializeObject(JObject.Parse(content)[“value”].ToString());
//...
}
}   

您可以将标准响应处理与ResponseHandler类一起使用

            var batchResponseContent = new BatchResponseContent(batchResponse);
            var responses = await batchResponseContent.GetResponsesAsync();
            var responseHandler = new ResponseHandler(new Serializer());
            foreach (var response in responses)
            {
                if (response.Value.IsSuccessStatusCode)
                {
                    var events = responseHandler.HandleResponse<ICalendarEventsCollectionPage>(response.Value);
                    //...
                }
            }

var batchResponseContent=新的batchResponseContent(batchResponse);
var responses=等待batchResponseContent.GetResponseAsync();
var responseHandler=newresponsehandler(newserializer());
foreach(响应中的var响应)
{
if(响应.值.IsSuccessStatusCode)
{
var事件=responseHandler.HandlerResponse(response.Value);
//...
}
}
还有一种更简单的方法来创建原始请求

var request = graphServiceClient
        .Users[userEmail]
        .Calendar.Events
        .Request(new List<QueryOption>
        {
            new QueryOption("startDateTime", start.ToString("o")),
            new QueryOption("endDateTime", end.ToString("o"))
        }).GetHttpRequestMessage();
var请求=graphServiceClient
.用户[用户电子邮件]
.日历.活动
.请求(新列表)
{
新的查询选项(“startDateTime”,start.ToString(“o”),
新的查询选项(“endDateTime”,end.ToString(“o”))
}).GetHttpRequestMessage();

如果有人想要我提供的完整解决方案,我会发出这样的批处理请求,它们现在可以正常工作了。客户端库中存在序列化问题,但自从我问了这个问题()

//您需要这些包/名称空间
//
//
//
//
//
//使用Microsoft.Graph;
//使用Microsoft.Graph.Extensions;
//使用Microsoft.Graph.Auth;
//使用Microsoft.Identity.Client;
var secretentialclientapplication=secretentialclientapplicationbuilder
.创建(“您的客户ID”)
.WithTenantId(“您的租户ID”)
.WithClientSecret(“您的客户秘密”)
.Build();
var forUser=“您用户的电子邮件地址”;
var authenticationProvider=新客户端凭据Provider(机密客户端应用程序);
var graphServiceClient=新的graphServiceClient(authenticationProvider);
var eventRequest=graphServiceClient.Users[forUser].Calendar.CalendarView.Request(
新名单
{
新的查询选项(“startDateTime”,DateTime.UtcNow.Date.AddMonths(-3).ToString(“O”),
新的查询选项(“endDateTime”,DateTime.UtcNow.Date.ToString(“O”))
}
);
var batchRequestContent=新的batchRequestContent();
var reqId=batchRequestContent.AddBatchRequestStep(eventRequest);
//在此处添加第二个、第三个请求
var returnedResponse=await graphServiceClient.Batch.Request().PostAsync(batchRequestContent);
var batchEvts=等待返回的响应。GetResponseByIdAsync(请求ID);
//在这里阅读第二、第三个回答

感谢您的回复,这是可行的,但不幸的是,会弄乱结果的日期格式。有没有办法告诉格式化程序别管这些?dateformat问题是由sdk错误引起的,现在已经修复,请参阅:谢谢,我没有找到很多关于批处理功能的官方文档,这是因为该功能比较新吗?还是我必须去别处看看?@ArneDeruwe不幸的是,是的。我正在努力让这些文件出版。这里有一个如何使用它的例子,不幸的是,我仍然有一些问题。看来responsehandler无法处理“@odata.context”以及错误,我已经更新了我的原始版本question@ArneDeruwe很抱歉造成混淆,我的示例有一个错误。向ICalendarEventsCollectionPage传递接口可能就是问题所在。JSON.NET将无法实例化接口。我需要查一下该上哪门课。它可能是CalendarEventsCollectionPage,但我将进行验证。我忘了提到我已经尝试使用非接口变量,因为我怀疑有相同的情况,不幸的是,这会产生相同的错误
            var batchResponseContent = new BatchResponseContent(batchResponse);
            var responses = await batchResponseContent.GetResponsesAsync();
            var responseHandler = new ResponseHandler(new Serializer());
            foreach (var response in responses)
            {
                if (response.Value.IsSuccessStatusCode)
                {
                    var events = responseHandler.HandleResponse<ICalendarEventsCollectionPage>(response.Value);
                    //...
                }
            }

var request = graphServiceClient
        .Users[userEmail]
        .Calendar.Events
        .Request(new List<QueryOption>
        {
            new QueryOption("startDateTime", start.ToString("o")),
            new QueryOption("endDateTime", end.ToString("o"))
        }).GetHttpRequestMessage();
//You need these packages/namespaces
//<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
//<PackageReference Include="Microsoft.Graph" Version="1.20.0" />
//<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.0" />
//<PackageReference Include="Microsoft.Graph.Core" Version="1.19.0-preview.3" />
//<PackageReference Include="Microsoft.Identity.Client" Version="4.3.0" />

//using Microsoft.Graph;
//using Microsoft.Graph.Extensions;
//using Microsoft.Graph.Auth;
//using Microsoft.Identity.Client;      
var confidentialClientApplication = ConfidentialClientApplicationBuilder
              .Create("YOUR CLIENT ID")
              .WithTenantId("YOUR TENANT ID")
              .WithClientSecret("YOUR CLIENT SECRET")
              .Build();

        var forUser = "YOUR USER'S EMAIL ADDRESS";

        var authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);
        var graphServiceClient = new GraphServiceClient(authenticationProvider);

        var eventRequest = graphServiceClient.Users[forUser].Calendar.CalendarView.Request(
            new List<QueryOption>
              {
                  new QueryOption("startDateTime", DateTime.UtcNow.Date.AddMonths(-3).ToString("O")),
                  new QueryOption("endDateTime", DateTime.UtcNow.Date.ToString("O"))
              }
           );

        var batchRequestContent = new BatchRequestContent();

        var reqId = batchRequestContent.AddBatchRequestStep(eventRequest);
        // add second, 3rd request here

        var returnedResponse = await graphServiceClient.Batch.Request().PostAsync(batchRequestContent);
        var batchEvts = await returnedResponse.GetResponseByIdAsync<CalendarEventsCollectionResponse>(reqId);
        // read second, 3rd responses here