我想优化对 MS GraphAPI 的 API 调用数量。
所以,我需要的是从我的日历中获取事件数量并与 graphAPI 日历事件同步。
数字可以从 0-1000(大约)变化
如何正确调用它?
以下是创建批量请求的示例:
public async Task<IEnumerable<string>> ExecuteBatchRequest(IEnumerable<Func<Task<string>>> batchRequests)
{
var batchRequestContent = new BatchRequestContent();
var requestIndex = 1;
var result = new List<string>();
foreach (var requestFunc in batchRequests)
{
var request = await requestFunc.Invoke();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, request);
batchRequestContent.AddBatchRequestStep(httpRequestMessage, requestIndex.ToString());
requestIndex++;
}
var batchResponse = await _graphServiceClient.Batch.Request().PostAsync(batchRequestContent);
foreach (var responseFunc in batchRequests)
{
var response = await batchResponse.GetResponseByIdAsync<string>(requestIndex.ToString());
result.Add(response.Result);
requestIndex++;
}
return result;
}
您有更好的代码的想法吗?
如果您的日历中有
0-1000
事件,您可以使用 JSON ID format
创建一个类,然后在 Azure Functions 代码中调用它,如下所示:-
我已经与 Microsoft Graph API 用户复制了相同的场景,因为我的目录中有多个用户:-
我的Azure Functions代码:-
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace FunctionApp1
{
public class User
{
public string Id { get; set; }
public string DisplayName { get; set; }
// Add other properties as needed based on the Graph API response
}
public class GraphApiResponse<T>
{
[JsonProperty("@odata.context")]
public string Context { get; set; }
public T Value { get; set; }
}
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var token = await GetAccessToken("xxxxxxaf9038592395", "xxxxx26a31435cb", "xxxxxa2Hr3wUzLFlwpK4b4M");
var users = await GetUsers(token);
return new OkObjectResult(users);
}
private static async Task<string> GetAccessToken(string tenantId, string clientId, string clientSecret)
{
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var result = await credentials.GetTokenAsync(new TokenRequestContext(new[] { "https://graph.microsoft.com/.default" }), default);
return result.Token;
}
private static async Task<List<User>> GetUsers(string token)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://graph.microsoft.com/v1.0/")
};
string URI = $"users";
httpClient.DefaultRequestHeaders.Remove("Authorization");
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
HttpResponseMessage response = await httpClient.GetAsync(URI);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var responseWrapper = JsonConvert.DeserializeObject<GraphApiResponse<List<User>>>(content);
if (responseWrapper != null)
{
return responseWrapper.Value;
}
}
// Handle the failure case or empty response
return new List<User>();
}
}
}
输出:-
对于日历事件:-
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace FunctionApp1
{
public class Event
{
public string Id { get; set; }
public string Subject { get; set; }
// Add other properties as needed based on the Graph API response for events
}
public class GraphApiResponse<T>
{
[JsonProperty("@odata.context")]
public string Context { get; set; }
public T Value { get; set; }
}
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var userId = "UserId"; // Replace with the actual user ID
var calendarId = "CalendarId"; // Replace with the actual calendar ID
var token = await GetAccessToken("YourTenantId", "YourClientId", "YourClientSecret");
var events = await GetEvents(token, userId, calendarId);
return new OkObjectResult(events);
}
private static async Task<string> GetAccessToken(string tenantId, string clientId, string clientSecret)
{
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var result = await credentials.GetTokenAsync(new TokenRequestContext(new[] { "https://graph.microsoft.com/.default" }), default);
return result.Token;
}
private static async Task<List<Event>> GetEvents(string token, string userId, string calendarId)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://graph.microsoft.com/v1.0/")
};
string URI = $"users/{userId}/calendars/{calendarId}/events";
httpClient.DefaultRequestHeaders.Remove("Authorization");
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
HttpResponseMessage response = await httpClient.GetAsync(URI);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var responseWrapper = JsonConvert.DeserializeObject<GraphApiResponse<List<Event>>>(content);
if (responseWrapper != null)
{
return responseWrapper.Value;
}
}
// Handle the failure case or empty response
return new List<Event>();
}
}
}
方法2:-
您可以利用下面的代码尝试在 Azure Function 中进行批处理来调用 Microsoft Graph API 并为您的获取日历事件 API 实现它:-
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace FunctionApp1
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var token = await GetAccessToken("83331f4e-7f45-4ce4-99ed-af9038592395", "c0c952e9-5254-45b5-b838-6d26a31435cb", "Fex8Q~i_cgyujE4aJ2dFkBa2Hr3wUzLFlwpK4b4M");
var results = await GetResults(token);
return new OkObjectResult(results);
}
private static async Task<string> GetAccessToken(string tenantId, string clientId, string clientSecret)
{
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var result = await credentials.GetTokenAsync(new TokenRequestContext(new[] { "https://graph.microsoft.com/.default" }), default);
return result.Token;
}
private static async Task<string> GetResults(string token)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://graph.microsoft.com/v1.0/")
};
var batchRequests = new List<HttpRequestMessage>();
const int numberOfRequests = 5; // Change this number based on your requirements
for (int i = 0; i < numberOfRequests; i++)
{
string requestUrl = $"https://graph.microsoft.com/v1.0/users/{i}"; // Use absolute URI for each request
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl);
httpRequestMessage.Headers.Add("Authorization", "Bearer " + token);
batchRequests.Add(httpRequestMessage);
}
var batchResponses = await SendBatchRequest(httpClient, batchRequests);
// Process batch responses here (if needed)
// For example, concatenate or structure the results in a specific way
var aggregatedResult = string.Join("\n", batchResponses);
return aggregatedResult;
}
private static async Task<List<string>> SendBatchRequest(HttpClient httpClient, List<HttpRequestMessage> batchRequests)
{
var batchEndpoint = "https://graph.microsoft.com/v1.0/$batch";
var batchContent = new MultipartContent("mixed");
foreach (var request in batchRequests)
{
var content = new HttpMessageContent(request);
batchContent.Add(content);
}
var batchResponse = await httpClient.PostAsync(batchEndpoint, batchContent);
var batchResponses = new List<string>();
if (batchResponse.IsSuccessStatusCode)
{
var responseContent = await batchResponse.Content.ReadAsStringAsync();
// Deserialize the batch response content to extract individual responses
var batchResponseData = JsonConvert.DeserializeObject<Dictionary<string, object>>(responseContent);
foreach (var responseItem in batchResponseData)
{
// Extract and handle individual batch responses
var responseData = responseItem.Value as Dictionary<string, object>;
var responseBody = responseData["body"].ToString(); // Extract the response body
batchResponses.Add(responseBody);
}
}
return batchResponses;
}
}
}
输出:-