【问题标题】:Forcing a new Id on an event insert在事件插入上强制使用新 ID
【发布时间】:2017-02-09 04:31:55
【问题描述】:

我正在使用 Google 日历 API,并且我正在将一个事件从一个日历复制到另一个日历,如下所示:

CalendarService service = new CalendarService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = this.ApplicationName
            });
CalendarListResource.ListRequest calRequest = service.CalendarList.List();
calRequest.MinAccessRole = CalendarListResource.ListRequest.MinAccessRoleEnum.Owner;
CalendarList calendars = calRequest.Execute();
CalendarListEntry selectedCalendar = calendar.Items[0];

EventsResource.ListRequest eventRequest = service.Events.List(selectedCalendar.Id);
eventRequest.TimeMin = DateTime.Now;
eventRequest.ShowDeleted = false;
eventRequest.SingleEvents = true;
eventRequest.MaxResults = 50;
eventRequest.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime;
Events events = eventRequest.Execute();

Event currentEvent = events.Items[0];
EventsResource.InsertRequest copyRequest = service.Events.Insert(currentEvent, calendarToCopyTo.Id);
copyRequest.Execute();

效果很好....第一次。第二次,它抛出一个错误,因为事件 ID 在calendarToCopyTo 上不再是唯一的(即使我删除了刚刚创建的事件并重试)。我的问题是:如何在我“插入”的事件中强制生成一个新的 ID?我在这些行之前尝试过currentEvent.Id = "";,但这似乎不起作用。

Google.Apis.Requests.RequestError 请求的标识符已经 存在。 [409] 错误 [ 消息 [已请求的标识符 存在。]位置[-]原因[重复]域[全局]]

根据这个example(.NET),我可能应该创建一个新的Event 对象(基于currentEvent),然后将其作为参数发送到插入请求。所以这里的另一个问题是:将所有属性从一个Event 变量(这里是currentEvent)复制到另一个变量的最简单方法是什么?

【问题讨论】:

  • 你能从 currentEvent 对象中删除 id 吗?或者可能将对象克隆到一个新对象中,以便删除 id?这对我来说听起来像是一个奇怪的错误。谷歌应该在插入时创建 ID,我会认为并忽略您发送的任何 ID。请问您遇到的具体错误是什么?
  • 是的,我希望 Google 每次都会为 calendarToCopyTo 上的新事件创建一个新 ID(无论您发送的事件的 ID 是什么)。异常的确切消息是:Google.Apis.Requests.RequestError The requested identifier already exists. [409] Errors [ Message[The requested identifier already exists.] Location [ - ] Reason[duplicate] Domain[global] ]developers.google.com/google-apps/calendar/v3/errors 告诉我我需要生成一个新 ID,但我不知道该怎么做(除了创建一个新的 Event 对象)
  • 你能把剩下的代码贴出来吗?你的 currentEvent 怎么样?
  • @DaImTo 我用更多代码更新了问题

标签: c# .net google-api google-calendar-api google-api-dotnet-client


【解决方案1】:

好的,这是我学到的(以及我想出的解决方案):

首先,如果您想使用我上面的代码,则必须在初始化 copyRequest 之前调用这两行代码:

currentEvent.Id = "";
currentEvent.ICalUID = "";

(因为IdICalUID 都用作ID,所以都必须重置)。 此处的重要提示:如果您稍后要使用 currentEvent 调用诸如 UpdateRequest 之类的东西,则会出现问题,因为您清除了该对象的 Id(因为 UpdateRequest 需要 eventId 作为参数 - 所以即使如果您从之前保存它,则必须在初始化该请求之前再次“重新设置” Id 和 ICalUID)。 [ICalUID 本质上等于Id + "@google.com"]

我的解决方案:

我没有保存 Id 和 ICalUID,清除它,复制事件,然后在我的 UpdateRequest 之前将它们设置回,而是创建了一个克隆方法来克隆事件:

private Event clone(Event eventToClone)
{
    Event result = new Event();

    foreach (PropertyInfo property in typeof(Event).GetProperties())
    {
        if (property.CanRead)
            property.SetValue(result, property.GetValue(eventToClone, null));
    }

    return result;
}

所以现在我将事件复制到另一个日历的代码变成了这样:

Event newEvent = clone(currentEvent);
newEvent.Id = "";
newEvent.ICalUID = "";
EventsResource.InsertRequest copyRequest = service.Events.Insert(newEvent, calendarToCopyTo.Id);
copyRequest.Execute();

希望这对将来的某人有所帮助!

【讨论】:

    【解决方案2】:

    你可以使用try catch,如果不存在则创建,否则更新,如下所示:

    try
    {
        service.Events.Insert(newEvent, calendarId).Execute();
    }
    catch (Exception)
    {
        service.Events.Update(newEvent, calendarId, newEvent.Id).Execute();
    }
    

    在我的解决方案中效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多