使用 Exchange 中的 EWS 处理 Exchange 邮箱项目

了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 创建、获取、更新和删除项目。

您可以使用 EWS 托管 API 或 EWS 处理邮箱中的项目。 可以使用泛型项 EWS 托管 API Item 对象或 EWS Item 类型 来执行一些操作(获取某项或使用项的标识符删除项);但是,大多数情况下您需要使用 强类型项执行获取或更新操作,因为您将需要访问特定于强类型项的属性。

例如,您无法使用泛型项检索某个项包含开始日期和结束日期的项 - 您需要一个 EWS 托管 API Appointment 对象或 EWS CalendarItem 类型来执行此操作。 如果您正在使用 EWS 托管 API,您总是需要创建强类型项,因为泛型 Item 类没有构造函数。 如果您正在处理非强类型项,您始终可以使用基 Item 类来处理该项。

表 1. 用于处理项的 EWS 托管 API 方法和 EWS 操作

若要... EWS 托管的 API 方法 EWS 操作
创建泛型项
无。 您只能通过使用 EWS 托管 API 创建特定项类型;不能创建泛型项。
CreateItem
获取项
Item.Bind
GetItem
更新项
Item.Update
UpdateItem
删除项
Item.Delete
DeleteItem

在本文中,您将了解到何时可以使用泛型基类以及何时需要使用强类型项来完成您的任务。 代码示例将演示如何使用基类,以及不能使用基类或它不符合您需求时应该怎么做。

使用 EWS 托管 API 创建项

EWS 托管 API 没有公共构造函数用于 Item 类,因此您必须使用您想要创建的特定项类型的构造函数来创建项。 例如,使用 EmailMessage 类构造函数来创建新的电子邮件,以及使用 Contact 类构造函数创建新联系人。 同样,服务器从不在响应中返回泛型 Item 对象;所有泛型项作为 EmailMessage 对象返回。

当您确定要创建的项的类型时,您只需几个步骤便可完成任务。 所有项类型的步骤类似:

  1. 初始化其中一个 Item 类的新实例,使用 ExchangeService 对象作为参数。

  2. 设置项上的属性。 架构对于每个项类型不同,所以不同的项可用的属性不同。

  3. 保存该项,或保存并发送该项。

例如,您可以创建 EmailMessage 对象,设置 SubjectBodyToRecipients 属性,然后通过使用 EmailMessage.SendAndSaveCopy 方法发送它。

// Create an email message and provide it with connection 
// configuration information by using an ExchangeService object named service.
EmailMessage message = new EmailMessage(service);
// Set properties on the email message.
message.Subject = "Company Soccer Team";
message.Body = "Are you interested in joining?";
message.ToRecipients.Add("sadie@contoso.com");
// Send the email message and save a copy.
// This method call results in a CreateItem call to EWS.
message.SendAndSaveCopy();

若要了解如何使用 EWS 托管 API 创建会议或约会项目,请参阅使用 Exchange 2013 中的 EWS 创建约会和会议

使用 EWS 创建项目

可以通过使用 EWS 创建泛型项或强类型项。 所有项类型的步骤类似:

  1. 使用 CreateItem 操作在 Exchange 存储中创建项。

  2. 使用 Items 元素包含要创建的一个或多个项。

  3. 设置项上的属性。

例如,您可以创建电子邮件并通过在下面的示例中使用代码来发送电子邮件。 这也是在您调用 SendAndSaveCopy 方法时 EWS 托管 API 发送的 XML 请求。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
               xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
               xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:CreateItem MessageDisposition="SendAndSaveCopy">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="sentitems" />
      </m:SavedItemFolderId>
      <m:Items>
        <t:Message>
          <t:Subject>Company Soccer Team</t:Subject>
          <t:Body BodyType="HTML">Are you interested in joining?</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>sadie@contoso.com </t:EmailAddress>
              </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

服务器使用 CreateItemResponse 邮件响应 CreateItem 请求,其中包括 ResponseCodeNoError(表示电子邮件创建成功)和新创建邮件的 ItemId

若要了解如何使用 EWS 创建会议或约会项目,请参阅使用 Exchange 2013 中的 EWS 创建约会和会议

使用 EWS 托管 API 获取项目

若要使用 EWS 托管 API 来获取项目,如果您知道要检索的项的 Item.Id ,您只需调用该项上的一个 Bind 方法,则会检索到该项。 最佳做法是建议您限制仅返回所需的属性。 此示例返回项 Id 属性和 Subject 属性。

此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。 局部变量 itemId 是要更新的项的 ID

// As a best practice, limit the properties returned to only those that are required.
PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.Subject);
// Bind to the existing item by using the ItemId.
// This method call results in a GetItem call to EWS.
Item item = Item.Bind(service, itemId, propSet);

如果您正在搜索满足特定条件的项,请执行以下操作:

  1. 绑定到包含要获取的项的文件夹。

  2. 实例化 SearchFilter.SearchFilterCollectionPropertySet 过滤要返回的项。

  3. 实例化 ItemViewCalendarView 对象指定要返回的项数。

  4. 调用 ExchangeService.FindItemsExchangeService.FindAppointments 方法。

例如,如果您想要检索收件箱中未读的电子邮件,请在下面的示例中使用代码。 此示例使用 SearchFilterCollectionFindItems 方法的结果限制为未读邮件,并限制 ItemView 以将结果限制为一个项。 此特定代码仅适用于 EmailMessage 对象,因为 EmailMessageSchema.IsRead 值属于 SearchFilter

// Bind the Inbox folder to the service object.
Folder inbox = Folder.Bind(service, WellKnownFolderName.Inbox);
// The search filter to get unread email.
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
ItemView view = new ItemView(1);
// Fire the query for the unread items.
// This method call results in a FindItem call to EWS.
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, sf, view);

或者,您可以使用 PropertySet 限制搜索结果,如以下代码示例中所示。 此示例使用 FindAppointments 方法来检索在接下来的 30 天中发生的最多五个约会。 当然,此代码仅适用于日历项。

// Initialize values for the start and end times, and the number of appointments to retrieve.
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(30);
const int NUM_APPTS = 5;
// Bind the Calendar folder to the service object.
// This method call results in a GetFolder call to EWS.
CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());
// Set the start and end time and number of appointments to retrieve.
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
// Limit the properties returned to the appointment's subject, start time, and end time.
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
// Retrieve a collection of appointments by using the calendar view.
// This method call results in a FindAppointments call to EWS.
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

请注意,服务器在 Bind 方法响应中返回的信息不同于服务器为 FindItemFindAppointment 方法响应返回的信息。 Bind 方法可返回所有架构化属性,而 FindItemFindAppointment 方法不会返回所有架构化属性。 所以如果需要完全访问项,您将需要使用 Bind 方法。 如果您不具备要检索的项的项 Id ,请使用 FindItemFindAppointment 方法来检索 ID,然后使用 Bind 方法来检索所需的属性。

若要了解如何使用 EWS 托管 API 获取会议或约会项目,请参阅使用 Exchange 中的 EWS 获取约会和会议

使用 EWS 获取项

如果您知道要检索的项的 ItemId,您可以通过使用 GetItem 操作获取项。

下面的示例演示 XML 请求通过特定 ItemId 获取某项的 "主题"。 这也是当在 ItemId 上调用 Bind 方法时 EWS 托管 API 发送的 XML 请求。 为了方便读取,已缩短一些属性和元素的值。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
               xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
               xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013" />
  </soap:Header>
  <soap:Body>
    <m:GetItem>
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:ItemIds>
        <t:ItemId Id="GJc/NAAA=" />
      </m:ItemIds>
    </m:GetItem>
  </soap:Body>
</soap:Envelope>

以下示例显示了服务器在处理 GetItem 操作后返回的 XML 响应。 该响应指示项已成功检索。 为了方便读取,已缩短某些属性和元素的值。

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15" 
                         MinorVersion="0" 
                         MajorBuildNumber="815" 
                         MinorBuildNumber="6" 
                         Version="V2_7" 
                         xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types" 
                         xmlns="https://schemas.microsoft.com/exchange/services/2006/types" 
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:GetItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
                       xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:GetItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:Items>
            <t:Message>
              <t:ItemId Id="GJc/NAAA=" ChangeKey="CQAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAGJd9Z"/>
              <t:Subject>Company Soccer Team</t:Subject>
            </t:Message>
          </m:Items>
        </m:GetItemResponseMessage>
      </m:ResponseMessages>
    </m:GetItemResponse>
  </s:Body>
</s:Envelope>

如果您不知道要检索的项的 ItemId,您可以使用 FindItem 操作来查找该项。 为了使用 FindItem 操作,必须首先标识要搜索的文件夹。 您可以通过使用其 DistinguinguishedFolderName 或使用 FolderId 标识该文件夹。 您可以使用 FindFolderSyncFolderHierarchy 操作来获取您需要的 FolderId。 然后使用 FindItem 操作来搜索该文件夹中与搜索筛选器匹配的结果。 与 EWS 托管 API 不同,EWS 不提供单独的约会查找操作。 FindItem 操作会检索所有类型的项。

下面的示例演示 XML FindItem 操作请求发送到服务器以查找在接下来的 30 天内出现的日历文件夹中的约会。 为了方便读取,已缩短一些属性和元素的值。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
               xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="calendar:Start" />
          <t:FieldURI FieldURI="calendar:End" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:CalendarView MaxEntriesReturned="5" StartDate="2013-10-16T17:04:28.722Z" EndDate="2013-11-15T18:04:28.722Z" />
      <m:ParentFolderIds>
        <t:FolderId Id="AAAEOAAA=" ChangeKey="AgAAABYAAAAqRr3mNdNMSasqx/o9J13UAAAAAAA3" />
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

服务器通过包含 NoErrorResponseCode 值的 FindItemResponse 消息响应 FindItem 请求,该值指示操作已成功完成。 如果任意日历项符合过滤条件,则它们将会包括在响应中。

请注意,服务器在 GetItem 操作响应中返回的信息不同于服务器在 FindItemFindAppointment 操作响应中返回的信息。 GetItem 方法可返回所有架构化属性,而 FindItemFindAppointment 操作不会返回所有架构化属性。 所以,如果您需要对项进行完全访问,您将需要使用 GetItem 操作。 如果您不具备要检索的项的 ItemId,请使用 FindItemFindAppointment 操作来检索 ItemId,然后使用 GetItem 操作来检索所需的元素。

若要了解如何使用 EWS 获取会议或约会项目,请参阅使用 Exchange 中的 EWS 获取约会和会议

使用 EWS 托管 API 更新项目

通过 EWS 托管 API 更新项的步骤对于所有项类型是相似的;但是,项属性对于每种项类型是不同的,Update 方法具有许多可选择的过载方法。 要更新项,请执行以下操作:

  1. 使用 Bind 方法获取最新版本的项,除非已经拥有该项。 若要更新特定于某个强类型项的属性,您需要绑定到该项类型。 若要更新可用的泛型项类型上可用的属性,您可以绑定到 Item 对象。

  2. 更新项上的属性。

  3. 调用 Update 方法。

例如,可以使用泛型项类型更新某个电子邮件的主题,如下面的示例代码中所示。

此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。 局部变量 itemId 是要更新的项的 ID

// Bind to the existing item, using the ItemId.
// This method call results in a GetItem call to EWS.
Item item = Item.Bind(service, itemId);
// Update the Subject of the email.
item.Subject = "New subject";
// Save the updated email.
// This method call results in an UpdateItem call to EWS.
item.Update(ConflictResolutionMode.AlwaysOverwrite);

若要了解如何使用 EWS 托管 API 更新会议或约会项目,请参阅使用 Exchange 中的 EWS 更新约会和会议

使用 EWS 更新项

要通过 EWS 更新某项,请执行以下操作:

  1. 使用 GetItem 操作获取最新版本的项,除非已拥有该项。

  2. 使用 UpdateItem 操作来指定字段,以更新并将新值分配给这些字段。

下面的示例显示了发送给服务器以更新电子邮件 "主题" 值的 XML UpdateItem 操作请求。 为了方便读取,已缩短一些属性和元素的值。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2010_SP1" />
  </soap:Header>
  <soap:Body>
    <m:UpdateItem MessageDisposition="SaveOnly" ConflictResolution="AlwaysOverwrite">
      <m:ItemChanges>
        <t:ItemChange>
          <t:ItemId Id="APdZjAAA=" ChangeKey="CQAAABYAAAAqRr3mNdNMSasqx/o9J13UAAAAPdgr" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>New subject</t:Subject>
              </t:Message>
            </t:SetItemField>
          </t:Updates>
        </t:ItemChange>
      </m:ItemChanges>
    </m:UpdateItem>
  </soap:Body>
</soap:Envelope>

服务器使用 UpdateItemResponse 邮件响应 UpdateItem 请求,该邮件中包括 NoErrorResponseCode 值,该值表示项更新成功。

若要了解如何使用 EWS 更新会议或约会项目,请参阅使用 Exchange 中的 EWS 更新约会和会议

使用 EWS 托管 API 删除项目

您可以通过将项移动到已删除项文件夹或垃圾站来删除项。 如果您知道要删除的项的 ItemId,只需调用该项的 Delete 方法。

如果您需要在删除项之前找到它,请执行以下操作:

  1. 调用 FindItemsFindAppointments 方法找到要删除的项。

  2. 实例化 PropertySet 并将其限制为要返回的属性,或者使用 SearchFilterCollection 查找特定项。

  3. 实例化 ItemViewCalendarView 指定要返回的项数。

  4. 调用 Delete 方法。

例如,下面的代码演示如何将电子邮件移动到已删除项文件夹。

此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。 局部变量 itemId 是要更新的项的 ID

// Bind to the existing item, using the ItemId.
// This method call results in a GetItem call to EWS.
Item item = Item.Bind(service, itemId);
// Delete the item by moving it to the Deleted Items folder.
// This method call results in a DeleteItem call to EWS.
item.Delete(DeleteMode.MoveToDeletedItems);

有关删除项目的更多详细信息,请参阅使用 Exchange 中的 EWS 删除项目。 若要了解如何使用 EWS 托管 API 删除会议或约会项目,请参阅使用 Exchange 中的 EWS 删除约会和取消会议

使用 EWS 删除项

您可以通过使用 DeleteItem 操作删除项。

下面的示例显示了发送给服务器以将电子邮件移动到已删除项文件夹的 XML 请求。 为了方便读取,已缩短一些属性和元素的值。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2010_SP1" />
  </soap:Header>
  <soap:Body>
    <m:DeleteItem DeleteType="MoveToDeletedItems">
      <m:ItemIds>
        <t:ItemId Id="APdZjAAA=" ChangeKey="CQAAABYAAAAqRr3mNdNMSasqx/o9J13UAAANIFzC" />
      </m:ItemIds>
    </m:DeleteItem>
  </soap:Body>
</soap:Envelope>

服务器使用 DeleteItemResponse 邮件响应 DeleteItem 请求,该邮件中包括 NoErrorResponseCode 值,该值表示项删除成功。

有关删除项目的更多详细信息,请参阅使用 Exchange 中的 EWS 删除项目。 若要了解如何使用 EWS 删除会议或约会项目,请参阅使用 Exchange 中的 EWS 删除约会和取消会议

将项目移动或复制到另一个邮箱

您可以使用 ExportItemsUploadItems 操作在邮件之间移动或复制项。 若要了解更多信息,请参阅 导出和导入 Exchange 中使用 EWS 的项目

另请参阅