Преобразование этого кода для использования Microsoft Graph в пакетном режиме - PullRequest
0 голосов
/ 05 ноября 2018

Вот мой код для удаления набора записей календаря:

public async Task<bool> DeleteCalendarEvents(SettingsBase oSettings)
{
    try
    {
        var oEvents = await _graphClient
                                .Me
                                .Calendars[oSettings.CalendarID]
                                .Events
                                .Request()
                                .Select("Start,Subject,Id")
                                .Top(50)
                                .Filter(oSettings.GetFilterString())
                                .OrderBy("start/DateTime")
                                .GetAsync();

        List<Event> listEvents = new List<Event>();

        listEvents.AddRange(oEvents);
        while (oEvents.NextPageRequest != null)
        {
            oEvents = await oEvents.NextPageRequest.GetAsync();
            listEvents.AddRange(oEvents);
        }

        foreach (Event oEvent in listEvents)
        { 
            await _graphClient.Me.Events[oEvent.Id].Request().DeleteAsync();
        }
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
        Console.WriteLine("DeleteCalendarEvents: See error log.");
        return false;
    }

    return true;
}

У меня есть метод, который добавляет новые события в календарь:

public async Task<bool> AddEventsToCalendar(MWBData.MWBCalendarData oData)
{
    if (oData.SettingsMWB.CalendarEntryType != "CLM_MidweekMeeting")
    {
        SimpleLog.Log("AddEventsToCalendar: CalendarEntryType is not set to CLM_MidweekMeeting.", SimpleLog.Severity.Error);
        Console.WriteLine("AddEventsToCalendar: See error log.");
        return false;
    }

    try
    {
        // Now create the new events
        foreach (EventWeek oWeek in oData.Weeks)
        {
            bool bSuccess = await AddEventToCalendar(oWeek, oData.SettingsMWB);
            if(bSuccess)
            {
                // Now create any Weekend Meeting events
                if(oWeek.WeekendMeeting.Included)
                {
                    bSuccess = await AddEventToCalendar(oWeek.WeekendMeeting, oData.SettingsMWB);
                    if(!bSuccess)
                    {
                        Console.WriteLine("AddEventsToCalendar: See error log.");
                        return false;
                    }
                }
            }
            else
            {
                Console.WriteLine("AddEventToCalendar: See error log.");
                return false;
            }
        }
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
        Console.WriteLine("AddEventsToCalendar: See error log.");
        return false;
    }

    return true;
}

Как видите, для каждого события он вызывает AddEventToCalendar. Этот метод частично создает событие, подобное этому:

// Add the event
Event createdEvent = await _graphClient.Me.Calendars[oSettings.CalendarID].Events.Request().AddAsync(new Event
{
    Subject = oEvent.GetSubject(),
    Body = body,
    Start = startTime,
    End = endTime,
    IsAllDay = oEvent.IsAllDayEvent(),
    IsReminderOn = bSetReminder,
    ReminderMinutesBeforeStart = bSetReminder ? iReminderMinutes : (int?)null,
    Location = location,
    SingleValueExtendedProperties = extendedProperties,
    Sensitivity = oSettings.SetCalendarPrivate ? Sensitivity.Private : Sensitivity.Normal
});

Теперь я знаю, что Microsoft Graph поддерживает пакетный режим с использованием JSON. Но я в растерянности относительно того, как реализовать это с тем, что я написал. Имеет смысл попытаться преобразовать мой код в список пакетных операций, чтобы уменьшить количество вызовов.

Как мне это сделать?

Обновление

Я нашел эту статью , но я не уверен, имеет ли она отношение и что мне следует делать. Так что я все равно буду признателен за любые конкретные рекомендации, как это сделать. Я уверен, что другие потенциальные пользователи выиграют от этого очень сильно - или будут перенаправлены на существующий ресурс, который я пропустил. Спасибо.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Даже если пакетный запрос еще не поддерживается , вы можете рассмотреть следующее подтверждение концепции , демонстрирующее, как реализовать базовую поддержку для извлечения объектов поверх msgraph-sdk-dotnet:

//1.Construct a Batch request 
var batchRequest = new BatchRequest(); 
//2. Add sub queries. Two parameters needs to be specified: a request and a result object                 
batchRequest.AddQuery(graphClient.Users[loginName].Request(), typeof(Microsoft.Graph.User));
batchRequest.AddQuery(graphClient.Sites["root"].Request(),typeof(Microsoft.Graph.Site));
//3. Execute Batch request
var result = await graphClient.GetBatchAsync(batchRequest);  

где BatchRequest класс вводит поддержку пакетного запроса

public class BatchRequest
{

    private Dictionary<string, IBaseRequest> _queriesTable = new Dictionary<string, IBaseRequest>();
    private Dictionary<string,Type> _resultsTable = new Dictionary<string, Type>();

    public KeyValuePair<IBaseRequest, Type> this[string queryId]
    {
        get
        {
            return new KeyValuePair<IBaseRequest,Type>(_queriesTable[queryId], _resultsTable[queryId]);
        }
    }


    public void AddQuery(IBaseRequest query, Type entityType)
    {
        var queryId = Guid.NewGuid().ToString();
        _resultsTable[queryId] = entityType;
        _queriesTable[queryId] = query;
    } 


    /// <summary>
    /// Construct JSON batch request https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching
    /// </summary>
    /// <param name="client"></param>
    /// <returns></returns>
    public HttpRequestMessage ToMessage(GraphServiceClient client)
    {
        var batchMessage = new HttpRequestMessage();
        batchMessage.RequestUri = new Uri("https://graph.microsoft.com/v1.0/$batch");
        batchMessage.Method = HttpMethod.Post;
        batchMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        dynamic payload = new ExpandoObject();
        payload.requests = _queriesTable.Select(kv =>
        {
            var message = kv.Value.GetHttpRequestMessage();
            dynamic request = new ExpandoObject();
            request.id = kv.Key; 
            request.method = message.Method.ToString();
            request.url = message.RequestUri.AbsoluteUri.Replace(client.BaseUrl,string.Empty);
            if(message.Content != null)
                request.body = message.Content;

            request.headers = message.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault());
            return request;
        });
        var jsonPayload = client.HttpProvider.Serializer.SerializeObject(payload);
        batchMessage.Content = new StringContent(jsonPayload,Encoding.UTF8,"application/json");
        return batchMessage;
    }

}

и GetBatchAsync - это метод расширения для выполнения пакетного запроса:

public static class GraphServiceClientExtensions
{
    public static async Task<List<object>> GetBatchAsync(this GraphServiceClient client, BatchRequest request)
    {
        var batchMessage = request.ToMessage(client);
        await client.AuthenticationProvider.AuthenticateRequestAsync(batchMessage);
        var response = await client.HttpProvider.SendAsync(batchMessage);

        var content = await response.Content.ReadAsStringAsync();
        var json = JObject.Parse(content);
        var entities = json["responses"].Select(item =>
        {
            var queryId = (string)item["id"];
            var entityPayload = JsonConvert.SerializeObject(item["body"]);
            var subRequest = request[queryId];
            var entity = JsonConvert.DeserializeObject(entityPayload, subRequest.Value);
            return entity;
        }); 
        return entities.ToList();
    }
}

Суть: Microsoft.Graph.BatchSupport.cs

Как я уже сказал, это всего лишь подтверждение концепции, и в этой реализации поддерживается только извлечение сущностей, поэтому, если вы хотите реализовать другие операции, такие как удаление, вы можете использовать его в качестве отправной точки

Результаты

enter image description here

0 голосов
/ 06 ноября 2018

Это не поддерживается в библиотеке графов.

https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/136

Обходной путь для вас, используйте HttpClient для запроса партия конечная точка,

Mock jsonObject (Вам нужно использовать StringBuilder или что-то подобное для создания строки, используйте / foreach, чтобы перебрать список событий, а затем добавить информацию об элементе к объекту json, просто не забудьте увеличить значение идентификатора ):

Примечание : Вложенный json, похоже, не работает на Graph, поэтому на этом рабочем месте все еще требуется проверка.

    {
      "requests": [
        {
          "id": "1",
         "url": "/me",
          "method": "POST",
          "body": {
  "subject": "Let's go for lunch",
  "body": {
    "contentType": "HTML",
    "content": "Does late morning work for you?"
  },
  "start": {
      "dateTime": "2017-04-15T12:00:00",
      "timeZone": "Pacific Standard Time"
  },
  "end": {
      "dateTime": "2017-04-15T14:00:00",
      "timeZone": "Pacific Standard Time"
  },
  "location":{
      "displayName":"Harry's Bar"
  },
  "attendees": [
    {
      "emailAddress": {
        "address":"samanthab@contoso.onmicrosoft.com",
        "name": "Samantha Booth"
      },
      "type": "required"
    }
  ]
},
          "headers": {
            "Content-Type": "application/json"
          }
        },
        {
          "id": "2",
         "url": "/me",
          "method": "POST",
          "body": {
  "subject": "Let's go for lunch",
  "body": {
    "contentType": "HTML",
    "content": "Does late morning work for you?"
  },
  "start": {
      "dateTime": "2017-04-15T12:00:00",
      "timeZone": "Pacific Standard Time"
  },
  "end": {
      "dateTime": "2017-04-15T14:00:00",
      "timeZone": "Pacific Standard Time"
  },
  "location":{
      "displayName":"Harry's Bar"
  },
  "attendees": [
    {
      "emailAddress": {
        "address":"samanthab@contoso.onmicrosoft.com",
        "name": "Samantha Booth"
      },
      "type": "required"
    }
  ]
},
          "headers": {
            "Content-Type": "application/json"
          }
        },
        {
          "id": "3", 
          "url": "/me",
          "method": "POST",
          "body": {
  "subject": "Let's go for lunch",
  "body": {
    "contentType": "HTML",
    "content": "Does late morning work for you?"
  },
  "start": {
      "dateTime": "2017-04-15T12:00:00",
      "timeZone": "Pacific Standard Time"
  },
  "end": {
      "dateTime": "2017-04-15T14:00:00",
      "timeZone": "Pacific Standard Time"
  },
  "location":{
      "displayName":"Harry's Bar"
  },
  "attendees": [
    {
      "emailAddress": {
        "address":"samanthab@contoso.onmicrosoft.com",
        "name": "Samantha Booth"
      },
      "type": "required"
    }
  ]
},
          "headers": {
            "Content-Type": "application/json"
          }
        }
      ]
    }

Выполнить код:

var content = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json"); 
var result = await client.PostAsync(url, content);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...