简体   繁体   English

通过EWS访问其他用户的Exchange邮箱时发生ErrorMissingEmailAddress错误

[英]ErrorMissingEmailAddress error when accessing other user's Exchange mailbox by EWS

I'm using EWS Managed API to read emails from Inbox and subfolders. 我正在使用EWS托管API从收件箱和子文件夹中读取电子邮件。 When I connect as the mailbox owner with username & password auth it all works fine, but when I connect as a service account using windows auth I get an error when accessing the subfolders. 当我使用用户名和密码auth作为邮箱所有者连接时,一切正常,但是当我使用Windows auth作为服务帐户连接时,访问子文件夹时出现错误。 The service account has been granted Full Access to the mailbox it's connecting to. 该服务帐户已被授予对与其连接的邮箱的完全访问权限。 The service account doesn't have its own mailbox. 服务帐户没有自己的邮箱。 The error is: 错误是:

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)

This is a pretty common error to get when you're using delegate access to a mailbox (ie not connecting to a mailbox you own) and you connect to a Well Known mailbox without specifying the mailbox owner. 当您使用对邮箱的委托访问(即,不连接到您拥有的邮箱)并且连接到知名邮箱而不指定邮箱所有者时,这是一个非常常见的错误。 There's an easy fix to that: you create a FolderId object using a Mailbox object with the primary smtp address of the mailbox you want to connect to, eg 有一个简单的解决方法:使用带有要连接的邮箱的主要smtp地址的Mailbox对象创建FolderId对象,例如

var theMailboxEmailAddress = "johnsmith@example.com";
var folderId = new FolderId(WellKnownFolderName.Inbox,
                      new Mailbox(theMailboxEmailAddress);
var items = myExchangeService.FindItems(folderId, anItemView);

However, my case isn't that easy. 但是,我的情况并不容易。 I am specifying the mailbox where I can but I'm getting the error when I'm calling FindItems on the subfolder. 我在指定邮箱的位置,但是在子文件夹中调用FindItems时出现错误。 There's no way to specify the mailbox when accessing the subfolder, because it should work without that. 在访问子文件夹时,无法指定邮箱,因为没有它,它应该可以工作。

According to this article ('Explicit access and EWS') the suggested method is: 根据本文 (“显式访问和EWS”),建议的方法是:

  • Start by using ' explicit access ': call FindFolder() with a DistinguishedFolderId (aka WellKnownFolderName ), passing a MailBox param to identify the mailbox owner. 通过使用“开始明确的访问 ”:调用FindFolder()DistinguishedFolderId (又名WellKnownFolderName ),传递MailBox参数去找出邮箱所有者。
    • That works fine for me, I'm able to get a list of the folders beneath Inbox and get the folder ItemId values 这对我来说很好,我可以在“收件箱”下获取文件夹列表并获取文件夹ItemId
  • Then use ' implicit access ': call service.FindItems(folderId, view) passing in the folderId retrieved from the previous step. 然后使用“ 隐式访问 ”:调用service.FindItems(folderId, view)传入从上一步中获取的folderId。 This fails for me, which is surprising. 这对我来说是失败的,这令人惊讶。

When I look at the EWS trace I can see that there are no DistinguishedFolderIds being sent in my FindItems() request. 当我查看EWS跟踪时,可以看到在FindItems()请求中没有发送DistinguishedFolderIds。 Here is the call that fails: 这是失败的呼叫:

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>

Here's the failure response: 这是失败响应:

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>

In the example above I was specifying ExchangeServerVersion Exchange2010_SP2 but I've tried also with Exchange2013. 在上面的示例中,我指定了ExchangeServerVersion Exchange2010_SP2,但我也尝试使用Exchange2013。 I'm connecting to an Exchange 2013 server. 我正在连接到Exchange 2013服务器。

A colleague tried the same thing using EWSEditor and got the same error. 一位同事使用EWSEditor尝试了相同的操作,并得到了相同的错误。 I've not double-checked that yet, but if so it suggests an EWS problem or an easy mistake to make when using the API. 我尚未对此进行仔细检查,但是如果是这样,则表明存在EWS问题或在使用API​​时容易犯的错误。

Also posted on MSDN forums here . 也张贴在MSDN论坛在这里

UPDATE 13-Oct-16: 更新16年10月13日:

Based on this Handling delegation-related errors in EWS in Exchange article I'm now wondering if this is a 'by design' limitation of Exchange. 基于Exchange中EWS中处理委派相关的错误,我现在想知道这是否是Exchange的“按设计”限制。 ie that if you want to look in non-well-known folders in an inbox you must have a mailbox, else it can't manage the permissions or something like that. 即,如果您要查看收件箱中的非知名文件夹,则必须有一个邮箱,否则它将无法管理权限或类似的操作。 In that article it says for ErrorMissingEmailAddress occurs when "Make a request using a delegate account that does not have a mailbox." 在该文章中,当“使用没有邮箱的委托帐户发出请求时”时,发生ErrorMissingEmailAddress and to handle it by "Adding a mailbox to the delegate's account." 并通过“向代表的帐户添加邮箱”来处理。

I'll check tomorrow whether adding a mailbox to the service account (which is otherwise not used at all) resolves the problem. 我明天将检查是否将邮箱添加到服务帐户(否则根本不会使用)是否可以解决问题。

Inspecting the (Microsoft.Exchange.WebServices.Data) FolderId class, it shows that when writing the Xml for the request, I believe it should include the Mailbox entry. 检查(Microsoft.Exchange.WebServices.Data)FolderId类,它表明为请求编写Xml时,我相信它应包括Mailbox条目。 It also shows that if you ToString() it, it should return the Folder ID and Mailbox ID. 它还显示,如果您使用ToString(),它将返回文件夹ID和邮箱ID。 I'd suggest confirming the mailbox you are getting with "new Mailbox(theMailboxEmailAddress)" is not null and the value is what you expect. 我建议确认使用“ new Mailbox(theMailboxEmailAddress)”获取的邮箱不为空,并且该值是您期望的值。 I also noticed the GetXmlElementName only returns DistinguishedFolderId when the FolderName within FolderId has a value - which from what I can see so far only occurs when the FolderId is created with a uniqueId string instead of a WellKnownFolderName. 我还注意到,当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();
    }

Update 1: I was still able to grab a quick trace. 更新1:我仍然可以快速浏览。 These were my results from some quick test code: 这些是我从一些快速测试代码获得的结果:

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>

Update 2: 更新2:

Confirmed that when using FolderId created with a uniqueId string, the trace is: 确认当使用通过uniqueId字符串创建的FolderId时,跟踪为:

    <m:ParentFolderIds>
      <t:FolderId Id="AQMkADY5YmEzNGJmLTljN2QtNDIwNS1hMWU2LTg4ADM4NDAzMDcxMGEALgAAA83F9dM/SH5Lnnw/6ftMMB0BANfWBWp5+bpGsBoSfk3Km5IAAAINKgAAAA==" ChangeKey="AQAAABYAAADX1gVqefm6RrAaEn5NypuSAAC8Vr7C" />
    </m:ParentFolderIds>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM