我使用EWS托管API从收件箱和子文件夹中读取电子邮件。当我作为邮箱所有者使用用户名&密码验证它一切正常,但当我使用Windows身份验证连接作为服务帐户时,访问子文件夹时出错。该服务帐户已被授予对其连接的邮箱的完全访问权限。服务帐户没有自己的邮箱。错误是:
Problem encountered while retrieving the email from exchange. Microsoft.Exchange.WebServices.Data.ServiceResponseException: When making a request as an account that does not have a mailbox, you must specify the mailbox primary SMTP address for any distinguished folder Ids.
at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
at MyMethod_That_Calls_ExchangeServer_FindItems(folderId, view)
当您使用对邮箱的委派访问权(即未连接到您拥有的邮箱)并且未指定邮箱所有者时连接到已知邮箱时,这是一个非常常见的错误。可以轻松解决此问题:使用FolderId
对象创建Mailbox
对象,其中包含要连接到的邮箱的主要smtp地址,例如:
var theMailboxEmailAddress = "johnsmith@example.com";
var folderId = new FolderId(WellKnownFolderName.Inbox,
new Mailbox(theMailboxEmailAddress);
var items = myExchangeService.FindItems(folderId, anItemView);
然而,我的情况并非那么容易。我正在指定邮箱,但是当我在子文件夹上调用FindItems
时,我收到错误。访问子文件夹时无法指定邮箱,因为没有它就可以工作。
根据this article('明确访问和EWS')建议的方法是:
FindFolder()
(又名DistinguishedFolderId
)致电WellKnownFolderName
,传递MailBox
参数识别邮箱所有者。
ItemId
值service.FindItems(folderId, view)
传递从上一步检索到的folderId。这对我来说是失败的,这是令人惊讶的。当我查看EWS跟踪时,我可以看到在我的FindItems()
请求中没有发送DistinguishedFolderIds。这是失败的电话:
Trace type: EwsRequest
Trace message: <Trace Tag="EwsRequest" Tid="13" Time="2016-10-13 12:50:05Z" Version="15.00.0913.015">
<?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="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010_SP2" />
</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:FieldURI FieldURI="message:From" />
<t:ExtendedFieldURI DistinguishedPropertySetId="InternetHeaders" PropertyName="X-MyApp-MailId" PropertyType="String" />
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="6" Offset="0" BasePoint="Beginning" />
<m:SortOrder>
<t:FieldOrder Order="Ascending">
<t:FieldURI FieldURI="item:DateTimeReceived" />
</t:FieldOrder>
</m:SortOrder>
<!-- Note below there's no DistinguishedFolderId, so nowhere to specify the mailbox -->
<m:ParentFolderIds>
<t:FolderId Id="AAMkAGU2NWRkNjYxLTI3YjktNDFkMi04ZmNlLWI0M2FmMGVmYzBhYwAuAAAAAAD/Z9M6ia69S5l65fo6tjEaAQAoQBtCK9L9S4ux7hB0Qcw/AAAIZFKVAAA=" />
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
</Trace>
这是失败的回应:
Trace type: EwsResponse
Trace message: <Trace Tag="EwsResponse" Tid="13" Time="2016-10-13 12:50:05Z" Version="15.00.0913.015">
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="847" MinorBuildNumber="31" Version="V2_8" 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 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<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="Error">
<m:MessageText>When making a request as an account that does not have a mailbox, you must specify the mailbox primary SMTP address for any distinguished folder Ids.</m:MessageText>
<m:ResponseCode>ErrorMissingEmailAddress</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
</Trace>
在上面的示例中,我指定了ExchangeServerVersion Exchange2010_SP2,但我也尝试过使用Exchange2013。我正在连接到Exchange 2013服务器。
一位同事使用EWSEditor尝试了同样的事情并得到了同样的错误。我还没有仔细检查过,但是如果是这样的话,那就表明在使用API时会出现EWS问题或容易犯的错误。
也发布在MSDN论坛here上。
更新13-Oct-16:
根据这篇Handling delegation-related errors in EWS in Exchange文章,我现在想知道这是否是一个&#39;设计&#39;交易所的限制。即,如果你想查看收件箱中的非知名文件夹,你必须有一个邮箱,否则它无法管理权限或类似的东西。在该文章中,它表示当{&#34}使用没有邮箱的代理帐户发出请求时会发生ErrorMissingEmailAddress
。&#34;并通过&#34;将邮箱添加到代理人的帐户来处理它。&#34;
我明天会检查是否向服务帐户添加邮箱(否则根本不使用)可以解决问题。
答案 0 :(得分:0)
检查(Microsoft.Exchange.WebServices.Data)FolderId类,它显示在为请求编写Xml时,我认为它应该包含Mailbox条目。它还显示如果你使用ToString()它,它应该返回文件夹ID和邮箱ID。我建议您确认使用的邮箱&#34;新邮箱(theMailboxEmailAddress)&#34;不是null,值是您所期望的。我还注意到,当FolderId中的FolderName有一个值时,GetXmlElementName只返回DistinguishedFolderId - 从目前为止我看到的只有当使用uniqueId字符串而不是WellKnownFolderName创建FolderId时才会出现。
internal override string GetXmlElementName()
{
if (!this.FolderName.HasValue)
{
return "FolderId";
}
return "DistinguishedFolderId";
}
public FolderId(WellKnownFolderName folderName, Mailbox mailbox) : this(folderName)
{
this.mailbox = mailbox;
}
internal override void WriteAttributesToXml(EwsServiceXmlWriter writer)
{
if (this.FolderName.HasValue)
{
writer.WriteAttributeValue("Id", this.FolderName.Value.ToString().ToLowerInvariant());
if (this.Mailbox != null)
{
this.Mailbox.WriteToXml(writer, "Mailbox");
return;
}
}
else
{
base.WriteAttributesToXml(writer);
}
}
public override string ToString()
{
if (!this.IsValid)
{
return string.Empty;
}
if (!this.FolderName.HasValue)
{
return base.ToString();
}
if (this.Mailbox != null && this.mailbox.IsValid)
{
return string.Format("{0} ({1})", this.folderName.Value, this.Mailbox.ToString());
}
return this.FolderName.Value.ToString();
}
更新1: 我仍然能够快速追踪。这些是我的一些快速测试代码的结果:
folder = New FolderId(WellKnownFolderName.Inbox)
Dim v As New ItemView(10, 0, OffsetBasePoint.Beginning)
Dim f As FindItemsResults(Of Item) = oService.FindItems(folder, v)
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="inbox" />
</m:ParentFolderIds>
Dim box As New Mailbox(mailboxAddress)
folder = New FolderId(WellKnownFolderName.Inbox, box)
Dim v As New ItemView(10, 0, OffsetBasePoint.Beginning)
Dim f As FindItemsResults(Of Item) = oService.FindItems(folder, v)
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="inbox">
<t:Mailbox>
<t:EmailAddress>****mailboxAddress****</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
更新2:
确认使用使用uniqueId字符串创建的FolderId时,跟踪为:
<m:ParentFolderIds>
<t:FolderId Id="AQMkADY5YmEzNGJmLTljN2QtNDIwNS1hMWU2LTg4ADM4NDAzMDcxMGEALgAAA83F9dM/SH5Lnnw/6ftMMB0BANfWBWp5+bpGsBoSfk3Km5IAAAINKgAAAA==" ChangeKey="AQAAABYAAADX1gVqefm6RrAaEn5NypuSAAC8Vr7C" />
</m:ParentFolderIds>