了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 作为代理人访问电子邮件。
可以使用 EWS 托管 API 或 EWS 向用户代理授予对邮箱所有者收件箱文件夹的访问权限。 然后,代理人可以代表邮箱所有者创建会议请求,搜索电子邮件,并根据邮箱所有者的收件箱文件夹检索、更新和删除电子邮件。
作为代理人,你使用的方法和操作访问邮箱所有者的“收件箱”文件夹与你用于访问没有代理人访问权限的收件箱文件夹的方法和操作相同。 main区别在于,你必须使用显式访问权限来查找或创建电子邮件项目,然后在确定项目 ID 后,可以使用隐式访问来获取、更新或删除项目。
表 1. 用于以委托身份访问电子邮件的 EWS 托管 API 方法和 EWS 操作
若要… | 使用此 EWS 托管 API 方法… | 使用此 EWS 操作… |
---|---|---|
以代理人身份创建和发送电子邮件 |
EmailMessage.保存FolderId 参数提供对邮箱所有者的 Drafts 文件夹的 显式访问 的位置 EmailMessage.SendAndSaveCopy,其中 FolderId 参数提供对邮箱所有者的“已发送邮件”文件夹的显式访问权限 |
CreateItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress SendItem,其中 Mailbox 元素指定邮箱所有者的 EmailAddress |
创建多个电子邮件作为代理人 |
ExchangeService.CreateItems,其中 FolderId 参数提供对邮箱所有者的收件箱文件夹的显式访问 |
CreateItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress |
以代理人身份搜索或查找电子邮件 |
ExchangeService.FindItems,其中 FolderId 参数提供对邮箱所有者的收件箱文件夹的显式访问权限 |
FindItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress |
以代理人身份获取电子邮件 |
EmailMessage.Bind |
GetItem |
以代理人身份更新电子邮件 |
EmailMessage.Bind 后跟 EmailMessage.Update |
GetItem,然后是 UpdateItem |
删除作为代理人的电子邮件 |
EmailMessage.Bind 后跟 EmailMessage.Delete |
GetItem,然后是 DeleteItem |
以代理人身份处理电子邮件时,请记住以下事项:
如果代理人只需要处理会议请求和响应,则代理不需要访问“收件箱”文件夹。 有关详细信息,请参阅 以代理人身份访问日历的先决条件任务。
当收件人收到代表邮箱所有者发送的邮件时,发件人将显示为“代表邮箱所有者委托”。
注意
在本文的代码示例中, primary@contoso.com 是邮箱所有者。
先决条件任务
必须先将用户 添加为具有 邮箱所有者收件箱文件夹权限的代理人,然后用户才能以代理人身份访问邮箱所有者的“收件箱”文件夹。
使用 EWS 托管 API 以委托身份创建和发送电子邮件
使用 EWS 托管 API,可以使用代理用户的服务对象代表邮箱所有者创建和发送电子邮件。 此示例演示如何使用 Save 方法将邮件保存在邮箱所有者的“草稿”文件夹中,然后使用 SendAndSaveCopy 方法发送邮件并将邮件保存在邮箱所有者的“已发送邮件”文件夹中。
此示例假定 服务 是代理的有效 ExchangeService 对象,并且已向代理授予 邮箱所有者的“收件箱”、“草稿”和“已发送邮件”文件夹的相应权限。
public static void DelegateAccessCreateEmail(ExchangeService service)
{
// 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");
// Save the email to the mailbox owner's Drafts folder.
// This method call results in a CreateItem call to EWS.
// The FolderId parameter contains the context for the
// mailbox owner's Inbox folder. Any additional actions
// taken on this message will be performed in the mailbox
// owner's mailbox.
message.Save(new FolderId(WellKnownFolderName.Drafts, new Mailbox("primary@contoso.com")));
// Send the email and save the message in the mailbox owner's
// Sent Items folder.
// This method call results in a SendItem call to EWS.
message.SendAndSaveCopy(new FolderId(WellKnownFolderName.SentItems, new Mailbox("primary@contoso.com")));
Console.WriteLine("An email with the subject '" + message.Subject + "' has been sent to '"
+ message.ToRecipients[0] + "' and saved in the Sent Items folder of the mailbox owner.");
}
使用 EWS 以代理人身份创建和发送电子邮件
EWS 使你能够使用代理用户的服务对象来代表邮箱所有者创建和发送电子邮件。 此示例演示如何使用 CreateItem 操作创建电子邮件和 SendItem 操作发送时间并将其保存在邮箱所有者的“已发送邮件”文件夹中。
这也是使用 Save 方法 创建和发送电子邮件时 EWS 托管 API 发送的第一个 XML 请求。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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="SaveOnly">
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="drafts">
<t:Mailbox>
<t:EmailAddress>primary@contoso.com</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</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 请求,该邮件包含 NoError的 ResponseCode 元素值,该值指示已成功创建和保存电子邮件。 响应还包含新创建的电子邮件的项目 ID。
为了提高可读性, 已缩短 ItemId 值。
<?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="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://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>
<m:CreateItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="iNRaAAA="
ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQPU" />
</t:Message>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
接下来,使用 SendItem 操作代表邮箱所有者发送邮件,并将其保存在邮箱所有者的“已发送邮件”文件夹中。
为了提高可读性, 已缩短 ItemId 值。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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:SendItem SaveItemToFolder="true">
<m:ItemIds>
<t:ItemId Id="iNRaAAA="
ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQPU" />
</m:ItemIds>
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="sentitems">
<t:Mailbox>
<t:EmailAddress>primary@contoso.com</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:SavedItemFolderId>
</m:SendItem>
</soap:Body>
</soap:Envelope>
服务器使用 SendItemResponse 邮件响应 SendItem 请求,该邮件包含 NoError的 ResponseCode 元素值,指示电子邮件已成功发送并保存到邮箱所有者的“已发送邮件”文件夹。
<?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="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://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>
<m:SendItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:SendItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:SendItemResponseMessage>
</m:ResponseMessages>
</m:SendItemResponse>
</s:Body>
</s:Envelope>
使用 EWS 托管 API 以代理人身份搜索电子邮件
若要搜索电子邮件,必须使用包含 FolderId 参数的 ExchangeService.FindItems 方法之一,以便指定邮箱所有者的“收件箱”文件夹。
static void DelegateAccessSearchEmailWithFilter(ExchangeService service)
{
// Limit the result set to 10 items.
ItemView view = new ItemView(10);
// Define the search filter.
SearchFilter.ContainsSubstring filter = new SearchFilter.ContainsSubstring(ItemSchema.Subject,
"soccer", ContainmentMode.Substring, ComparisonMode.IgnoreCase);
view.PropertySet = new PropertySet(ItemSchema.Subject,
ItemSchema.DateTimeReceived,
EmailMessageSchema.IsRead);
// Item searches do not support deep traversal.
view.Traversal = ItemTraversal.Shallow;
// Sorting.
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
try
{
// Call FindItems to find matching Inbox items.
// The parameters of FindItems must denote the mailbox owner,
// mailbox, and Inbox folder.
// This call results in a FindItem call to EWS.
FindItemsResults<Item> results = service.FindItems(new
FolderId(WellKnownFolderName.Inbox, "primary@contoso.com"),
filter, view);
foreach (Item item in results.Items)
{
Console.WriteLine("Subject: {0}", item.Subject);
Console.WriteLine("Id: {0}", item.Id.ToString());
if (item is EmailMessage)
{
EmailMessage message = item as EmailMessage;
Console.WriteLine("Read: {0}", message.IsRead.ToString());
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception while enumerating results: {0}", ex.Message);
}
}
在 FindItems 调用返回具有 ID 的响应后,可以使用 ID 和隐式访问来获取、更新或删除该电子邮件,并且无需指定邮箱所有者的 SMTP 地址。
使用 EWS 以代理人身份搜索电子邮件
EWS 使你能够使用委托用户的服务对象来搜索满足一组搜索条件的电子邮件。 此示例演示如何使用 FindItem 操作在所有者的收件箱文件夹中查找主题中包含单词“足球”的邮件。
这也是搜索电子邮件时 EWS 托管 API 发送 的 XML 请求。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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="item:DateTimeReceived" />
<t:FieldURI FieldURI="message:IsRead" />
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="10"
Offset="0"
BasePoint="Beginning" />
<m:Restriction>
<t:Contains ContainmentMode="Substring"
ContainmentComparison="IgnoreCase">
<t:FieldURI FieldURI="item:Subject" />
<t:Constant Value="soccer" />
</t:Contains>
</m:Restriction>
<m:SortOrder>
<t:FieldOrder Order="Descending">
<t:FieldURI FieldURI="item:DateTimeReceived" />
</t:FieldOrder>
</m:SortOrder>
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="inbox">
<t:Mailbox>
<t:EmailAddress>primary@contoso.com</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
服务器使用 FindItemResponse 消息来响应 FindItem 请求,其中包含 NoError 的 ResponseCode 元素值,指示已成功完成搜索。 响应包含满足搜索条件的任何电子邮件的 Message 元素。 在这种情况下,仅找到一封电子邮件。
为了便于阅读,已缩短 ItemId 元素的值。
<?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="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://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>
<m:FindItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="1"
TotalItemsInView="1"
IncludesLastItemInRange="true">
<t:Items>
<t:Message>
<t:ItemId Id="iNwoAAA="
ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQuu" />
<t:Subject>Soccer team</t:Subject>
<t:DateTimeReceived>2014-03-10T06:16:55Z</t:DateTimeReceived>
<t:IsRead>false</t:IsRead>
</t:Message>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
现在,你已获得符合条件的电子邮件的 ItemId ,可以使用 ItemId 和 隐式访问 来获取、更新或删除该电子邮件,并且无需指定邮箱所有者的 SMTP 地址。
使用 EWS 托管 API 以委托身份获取、更新或删除电子邮件项目
可以使用 EWS 托管 API 获取、更新或删除电子邮件,其方式与不使用委托访问时执行这些操作的方式相同。 唯一的区别在于 ,ExchangeService 对象适用于委托用户。 Bind 方法调用中包含的项目 ID 唯一标识邮箱存储中邮箱所有者的“收件箱”文件夹中的项目。
表 2. 使用电子邮件作为委托的 EWS 托管 API 方法
任务 | EWS 托管的 API 方法 | 代码示例 |
---|---|---|
获取电子邮件 |
绑定 |
使用 EWS 托管 API 获取项 |
更新电子邮件 |
绑定,然后是 更新 |
使用 EWS 托管 API 更新项 |
删除电子邮件 |
绑定,然后是 删除 |
使用 EWS 托管 API 删除项 |
使用 EWS 作为代理人获取、更新或删除电子邮件项目
可以使用 EWS 托管 API 获取、更新或删除电子邮件,其方式与不使用委托访问时执行这些操作的方式相同。 唯一的区别是服务对象适用于代理用户。 GetItem 请求中包含的项目 ID 唯一标识邮箱存储中邮箱所有者的“收件箱”文件夹中的项目。
表 3. 用于将电子邮件作为代理人处理的 EWS 操作
任务 | EWS 操作 | 代码示例 |
---|---|---|
获取电子邮件 |
GetItem |
使用 EWS 获取项 |
更新电子邮件 |
GetItem,然后是 UpdateItem |
使用 EWS 更新项 |
删除电子邮件 |
GetItem,然后是 DeleteItem |
使用 EWS 删除项 |