如何从 Exchange Server 2007 中提取公共日历数据?

Posted

技术标签:

【中文标题】如何从 Exchange Server 2007 中提取公共日历数据?【英文标题】:How to pull public calendar data from Exchange Server 2007? 【发布时间】:2013-04-30 17:01:46 【问题描述】:

我的任务很简单。我有一个公用文件夹(实际上是一个日历),我需要从两个日期之间提取所有会议。

我正在使用 Visual Studio 2010、ASP.Net 4.0、Microsoft Exchange Server Web Services (EWS) 和 Exchange Server 2007。

我已经使用以下代码成功地在我的个人日历中创建了一个项目:

public static string[] CreateAppointment() 

    // Set up the binding with credentials and URL.
    com.webmail.ExchangeServiceBinding binding = new com.webmail.ExchangeServiceBinding();
    binding.Credentials = new System.Net.NetworkCredential("steve.kershaw", "mypasswordhere", "domain.com");
    binding.Url = @"https://webmail.com/ews/exchange.asmx";

    // Creating new appointment item type 
    com.webmail.CalendarItemType appointment = new com.webmail.CalendarItemType();  

    // Add properties to the newly created appointment. 
    appointment.Importance = com.webmail.ImportanceChoicesType.Normal; 
    appointment.ImportanceSpecified = true; 
    appointment.ItemClass = "IPM.Appointment"; 
    appointment.Subject = "mySubject"; 
    appointment.Body = new com.webmail.BodyType(); 
    appointment.Body.BodyType1 = com.webmail.BodyTypeType.html; 
    appointment.Body.Value = "<b>Body</b>";
    appointment.Categories = new string[]  "Category Red", "Category Blue" ; 
    appointment.Start = new DateTime(2013,4,30,12, 30,0); 
    appointment.StartSpecified = true; 
    appointment.End = new DateTime(2013, 4, 30, 13, 0, 0); 
    appointment.EndSpecified = true; 
    appointment.IsAllDayEvent = false; 
    appointment.IsAllDayEventSpecified = true; 
    appointment.Location = "myOffice"; 
    appointment.LegacyFreeBusyStatus = com.webmail.LegacyFreeBusyType.Busy; 
    appointment.LegacyFreeBusyStatusSpecified = true; 
    appointment.ReminderIsSet = true; 
    appointment.ReminderIsSetSpecified = true; 
    appointment.ReminderMinutesBeforeStart = "60";  

    // Specify the destination folder 
    com.webmail.DistinguishedFolderIdType folder = new com.webmail.DistinguishedFolderIdType(); 
    folder.Id = com.webmail.DistinguishedFolderIdNameType.calendar;  

    // Create the NonEmptyArrayOfAllItemsType array that will contain the appointment. 
    com.webmail.NonEmptyArrayOfAllItemsType arrayOfItems = new com.webmail.NonEmptyArrayOfAllItemsType(); 
    arrayOfItems.Items = new com.webmail.ItemType[1];  

    // Add our appointment to the array. 
    arrayOfItems.Items[0] = appointment; 

    // Create the request. 
    com.webmail.CreateItemType createItemRequest = new com.webmail.CreateItemType();  

    // Set the required SendMeetingInvitations attribute 
    createItemRequest.SendMeetingInvitations = com.webmail.CalendarItemCreateOrDeleteOperationType.SendToNone; 
    createItemRequest.SendMeetingInvitationsSpecified = true;

    // Add the destination folder to the request. 
    createItemRequest.SavedItemFolderId = new com.webmail.TargetFolderIdType(); 
    createItemRequest.SavedItemFolderId.Item = folder;  

    // Add the items to the CreateItem request. 
    createItemRequest.Items = arrayOfItems;  

    // Return value containg changeKey and hash Id to identify our appointment(needed for deleteing etc.) 
    string[] changeKeyHashId = new string[2];  
    try 
    


        // Send the request - esb is a ExchangeServiceBinding object instance created in the Part 1 of this tutorial 
        com.webmail.CreateItemResponseType createItemResponse = binding.CreateItem(createItemRequest);  
        if (createItemResponse.ResponseMessages.Items == null || createItemResponse.ResponseMessages.Items.Length == 0) 
         
            return new string[]  "ERROR" ; 
         
        else 
         
            // Get the response message. 
            com.webmail.ResponseMessageType[] rmt = createItemResponse.ResponseMessages.Items;  
            if (rmt[0].ResponseClass != com.webmail.ResponseClassType.Success) 
                return new string[] 
                 "ERROR: " + rmt[0].MessageText 
                ; 
            else 
             
                foreach (com.webmail.ResponseMessageType rmtItem in rmt) 
                 
                    com.webmail.ArrayOfRealItemsType itemArray = (rmtItem as com.webmail.ItemInfoResponseMessageType).Items; 
                    com.webmail.ItemType[] items = itemArray.Items;  
                    // Get the return values 
                    changeKeyHashId[0] = items[0].ItemId.ChangeKey; 
                    changeKeyHashId[1] = items[0].ItemId.Id;
                 
             
         
     
    catch (Exception ex) 
     
        return new string[] 
         "ERROR: " + ex.Message ; 
      return changeKeyHashId; 

但是,我一直找不到任何代码来成功从任何日历(包括我自己的日历)中提取任何约会。我的代码的(当前)迭代在 com.webmail.GetItemResponseType resp = binding.GetItem(getItemType); 中返回“Id 格式错误”错误。返回 ResponseMessages.Items.MessageText 值。这会导致返回的项目为空值。 我的代码如下:

public static void GetCalendarItem()

    // Set up the binding with credentials and URL.
    com.webmail.ExchangeServiceBinding binding = new com.webmail.ExchangeServiceBinding();
    binding.Credentials = new System.Net.NetworkCredential("steve.kershaw", "mypasswordhere", "domain.com");
    binding.Url = @"https://webmail.com/ews/exchange.asmx";

    // Get the Itemtype...
    com.webmail.GetItemType getItemType = new com.webmail.GetItemType();

    ////getItemType.
    //com.webmail.GetItemResponseType getItemResponseType = binding.GetItem(getItemType);
    // Create the response shape.
    com.webmail.ItemResponseShapeType responseShape = new com.webmail.ItemResponseShapeType();
    responseShape.BodyType = com.webmail.BodyTypeResponseType.Text;
    responseShape.BodyTypeSpecified = true;
    responseShape.BaseShape = com.webmail.DefaultShapeNamesType.Default;
    // Add more properties to the request.
    com.webmail.PathToUnindexedFieldType[] sensitivity = new com.webmail.PathToUnindexedFieldType[1];
    sensitivity[0] = new com.webmail.PathToUnindexedFieldType();
    sensitivity[0].FieldURI = com.webmail.UnindexedFieldURIType.itemSensitivity;
    responseShape.AdditionalProperties = sensitivity;
    // Add the response shape to the request.
    getItemType.ItemShape = responseShape;

    // Identify the items to get.
    com.webmail.ItemIdType[] items = new com.webmail.ItemIdType[2];
    items[0] = new com.webmail.ItemIdType();
    items[0].Id = "AAAlAE1BQG1";
    items[0].ChangeKey = "DwAAABYAAAA";
    items[1] = new com.webmail.ItemIdType();
    items[1].Id = "AAAlAE1BQG1";
    items[1].ChangeKey = "DwAAABYAAAA";

    // Add items to the request.
    getItemType.ItemIds = items;

    try
    
        // Send the request and get the response.
        com.webmail.GetItemResponseType resp = binding.GetItem(getItemType);
        com.webmail.ArrayOfResponseMessagesType aormt = resp.ResponseMessages;
        com.webmail.ResponseMessageType[] rmta = aormt.Items;

        foreach (com.webmail.ResponseMessageType rmt in rmta)
        
            com.webmail.ItemInfoResponseMessageType iirmt = (rmt as com.webmail.ItemInfoResponseMessageType);
            com.webmail.ArrayOfRealItemsType aorit = iirmt.Items;
            com.webmail.ItemType[] myItems = aorit.Items;

            // Determine the type for each item and cast to the approriate type.
            foreach (com.webmail.ItemType it in myItems)
            
                // Check whether it is an e-mail.
                if (it is com.webmail.MessageType)
                
                    com.webmail.MessageType message = (it as com.webmail.MessageType);
                
                // Determine whether it is a calendar item.
                else if (it is com.webmail.CalendarItemType)
                
                    com.webmail.CalendarItemType calendar = (it as com.webmail.CalendarItemType);
                
                else
                
                    // Check for other item types.
                
            
        
    
    catch (Exception e)
    
        throw new Exception("GetItem failed");
    

有没有一种简单的方法可以在某个日期范围内将所有约会都拉到日历中?!

【问题讨论】:

我猜没人有答案!!! :-( 您的 ItemId 和 ChangeKey 看起来非常错误。他们应该是形式 CreateItem应该已经回到你这些ID SPAN> 【参考方案1】:

Steve,你从哪里得到你放入 GetItem 的 ID? 通常的路线是使用邮箱 smtp 和 from/to date 调用 FindItem。您可以使用 FindItem 获取大多数字段,但例如不是正文,因此您使用从 FindItem 返回的 ID 之一调用 GetItem。

请注意,FindItem 也会返回所有出现的重复事件,您可能希望首先从这些事件中获取主事件。 在Delete recurring calendar item with php EWS?查看我的回答

我不能给你任何 C 代码,我是通过我自己的 SOAP 调用在 Delphi 中完成的。

【讨论】:

以上是关于如何从 Exchange Server 2007 中提取公共日历数据?的主要内容,如果未能解决你的问题,请参考以下文章

powershell Exchange服务器将用户添加到公用文件夹。在Exchange Server 2007上工作

Microsoft Exchange Server日常维护-安装证书

Exchange Server 2007 / 2010 命令安装法

Exchange Server 2007的即将生命周期,您的计划是?

Exchange2007升级到Exchange2013——配置新旧版本共存

Exchange Server2010 升级至Exchange Server 2016--01(知识点)