API календаря Google возвращает 404 (не найдено) для другого запроса

#c# #.net #google-api #http-status-code-404 #google-calendar-api

#c# #.net #google-api #http-status-code-404 #google-calendar-api

Вопрос:

Я реализовал приложение в .NET, которое синхронизирует события Календаря Google с событиями моей базы данных. Он работает нормально, пока мне не понадобится использовать те же методы Google API, которым в качестве параметра требуется EventID, например delete, move, update . Моя проблема в том, что эти методы иногда работают, иногда нет. Я не могу понять, в чем на самом деле проблема и в каких ситуациях генерируется ошибка. Я также использовал игровую площадку OAuth 2.0 и опцию «Попробуйте этот API» в документации Google Calendar API для безуспешного тестирования (все еще ошибка 404).).

У меня есть несколько календарей в Google, созданных мной и предоставленных мне с полными разрешениями. Проблемы возникают без логики, независимо от того, являюсь ли я владельцем календаря или нет. Области, которые я использую: CalendarService.Область действия.Календарь, CalendarService.Область действия.CalendarEvents.

  1. Удалите событие из Календаря Google с помощью моего приложения.

    Это дает мне 404. Затем я попытался удалить то же событие в документации API Календаря Google — События: удалить. Все еще 404. Я проверил, существует ли событие, используя запросы Google OAuth. Удивительно, что он существует. Хорошо, давайте попробуем удалить его снова. Те же ошибки. Если я не потеряю терпения и попробую это достаточно, наступает момент, когда все работает нормально.

  2. Обновите событие.

    Та же проблема: не найдено.

  3. Переместить событие из одного календаря в другой.

    Та же проблема: не найдено. Но в этой ситуации я заметил разницу, используя документацию API Календаря Google — События: переместить опцию «Попробовать этот API»: она не работает, пока я не попытаюсь переместить событие из одного моего календаря (владельца) в другой мой (владелец). С этого момента все работает так, как должно, без каких-либо других ошибок (даже с общими календарями).

CalendarService.cs

 public CalendarService GetService()
{
    try
    {
         // Authenticated user credential
         var credential = GetUserCredential();
         if (credential == null)
             throw new ArgumentNullException("credential");

         // Create Calendar API service.
         return new CalendarService(new BaseClientService.Initializer()
         {
             HttpClientInitializer = credential,
             ApplicationName = ApplicationName
         });
    }
    catch (Exception ex)
    {
         throw new Exception("Get Calendar service failed.", ex);
    }
}

private UserCredential GetUserCredential()
{
    try
    {
         UserCredential credential;

         using (var stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read))
         {
             string credPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);

             // The file token.json stores the user's access and refresh tokens, and is created
             // automatically when the authorization flow completes for the first time.
             credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    userId,
                    CancellationToken.None,
                    new FileDataStore(credPath, true)
                    ).Resu<
          }
          credential.GetAccessTokenForRequestAsync();
          return credential;
     }
     catch (Exception ex)
     {
          throw new Exception("Get user credentials failed.", ex);
     }
}

public async Task MoveEvent(CalendarService service, string calendarId, string eventId, string destination)
{
    // Building the initial request amp; requesting data async
    await service.Events.Move(calendarId, eventId, destination).ExecuteAsync();
}
  

CalendarLogic.cs

 private GoogleCalendarData calendarData = new GoogleCalendarData();
private GoogleCalendarService calendarService = new GoogleCalendarService();

public async Task MoveAppEvents(string sourceCalendarId, string destinationCalendarId)
{
    //Here events from database inserted in Google are retrieved
    var events = await calendarData.GetEvents(null, false);
    events.Where(item => item.GoogleEventId != "")
            .ToList()
            .ForEach((async item => await calendarService.MoveEvent(calendarService.GetService(), sourceCalendarId, item.GoogleEventId, destinationCalendarId)));
}
  

CalendarController.cs

 private GoogleCalendarLogic googleCalendar = new GoogleCalendarLogic();

[Route("{calendarId}/appevents/move/{destination}")]
[HttpPost]
public async Task MoveAppEvents(string calendarId, string destination)
{
     await googleCalendar.MoveAppEvents(calendarId, destination);
}
  

Комментарии:

1. Как вы авторизуете своего клиента и подключаетесь ли вы от своего имени или от учетной записи службы?

2. @RafaGuillermo как пользователь, использующий аутентификацию Oauth2.

3. Можете ли вы опубликовать свой код аутентификации, а также вызовы ваших методов?

4. Я хочу изменить метод аутентификации, потому что я хочу использовать этот API из приложения Angular. Но я не уверен (пока), как именно я должен это сделать. Вместо GoogleWebAuthorizationBroker. AuthorizeAsync Я должен использовать GoogleAuthorizationCodeFlow в API (с той же логикой), а процесс аутентификации / согласия должен обрабатываться в приложении Angular. Это правильный поток?