Exchange Web 服务 (EWS) 链 FindItemType for itemItemclas & messageIsRead

Exchange Web service (EWS) chain FindItemType for itemItemclas & messageIsRead

高级程序员。

我正在使用我的 SSIS 脚本任务中引用的原始交换 Web 服务。

我的问题是,当我枚举邮箱或文件夹中的项目时,我不仅只对那些尚未阅读的项目感兴趣,而且我想忽略所有系统类型的邮件。所以我只想要项目,特别是消息,"itemclass" 是 "IPM.Note" 没有别的。

这是项目类型和消息的最终列表 classes https://msdn.microsoft.com/en-us/library/office/ff861573.aspx

我的代码可以成功处理收件箱中的未读项目

 'declare my find criteria, return only the IDs, from the inbox, for unread items
    Dim reqFindUnreadMailInInbox As FindItemType = New FindItemType With _
    {.Traversal = ItemQueryTraversalType.Shallow _
     , .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.IdOnly} _
     , .ParentFolderIds = New DistinguishedFolderIdType(0) {New DistinguishedFolderIdType With {.Id = DistinguishedFolderIdNameType.inbox}} _
     , .Restriction = New RestrictionType With _
        {.Item = New IsEqualToType With _
        {.Item = New PathToUnindexedFieldType With {.FieldURI = UnindexedFieldURIType.messageIsRead} _
                                                    , .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "0"}} _
                                                } _
        } _
    }

    'go fetch the response from exchange
    Dim resFindItemResponse As FindItemResponseType = esb.FindItem(reqFindUnreadMailInInbox)
    Dim resFindFolderMessages As FindItemResponseMessageType = resFindItemResponse.ResponseMessages.Items(0)
    Dim resFolderItems As ArrayOfRealItemsType = Nothing '= New ArrayOfRealItemsType

我遇到的问题是我想对返回的 itemClass 添加限制。但无法弄清楚如何向请求添加第二个限制。如果我更改我的搜索以从收件箱中提取所有项目而不考虑阅读状态但仅限于 itemClass IPM.Note (注意添加分页结果)

 Dim reqFindUnreadMailInInbox As FindItemType = New FindItemType With _
   {.Item = New IndexedPageViewType With {.MaxEntriesReturnedSpecified = True, .MaxEntriesReturned = "100", .BasePoint = IndexBasePointType.Beginning, .Offset = 0} _
    , .Traversal = ItemQueryTraversalType.Shallow _
    , .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.IdOnly} _
    , .ParentFolderIds = New DistinguishedFolderIdType(0) {New DistinguishedFolderIdType With {.Id = DistinguishedFolderIdNameType.inbox}} _
    , .Restriction = New RestrictionType With _
       {.Item = New IsEqualToType With _
                                   {.Item = New PathToUnindexedFieldType With {.FieldURI = UnindexedFieldURIType.itemItemClass} _
                                                , .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "IPM.Note"}} _
                                   } _
       } _
   }

下一段代码检查错误,并继续枚举 ID 并在一次调用中获取项目。如果我在响应返回后调试 resGetitem,我可以通过使用此查询 window 查看即时 window 来向下钻取并查看每个项目 class

?directcast(directcast(resGetItem.ResponseMessages.Items(0),ItemInfoResponseMessageType).Items.Items(0),MessageType)

我可以看到 "REPORTS.IPM.Note.NDR"。问题是我如何过滤初始调用以限制为仅 "IPM.Note"

 'if there was an error bur out and report
    If resFindFolderMessages.ResponseClass = ResponseClassType.[Error] Then
        Throw New Exception(resFindFolderMessages.MessageText)
    Else
        TraceLog.AppendLine("Inbox found, ID pulled back")
        If Not IsNothing(DirectCast(resFindFolderMessages.RootFolder.Item, ArrayOfRealItemsType).Items) Then
            resFolderItems = resFindFolderMessages.RootFolder.Item
            TraceLog.AppendLine(String.Format("found {0} unread mail - start processing", resFolderItems.Items.Count))
            'So we have the array of ids for the emails, now fetch the emails themselves
            Dim resItemIDs As ItemIdType() = Nothing
            'collect the ids up
            For x As Integer = 0 To resFolderItems.Items.Count - 1
                If IsNothing(resItemIDs) Then ReDim resItemIDs(0) Else ReDim Preserve resItemIDs(resItemIDs.Length)
                resItemIDs(x) = resFolderItems.Items(x).ItemId
            Next
            'go get the email messages
            Dim resGetItem As GetItemResponseType = esb.GetItem(New GetItemType With { _
                                                                .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.AllProperties _
                                                                                                             , .BodyType = BodyTypeResponseType.Text _
                                                                                                             , .BodyTypeSpecified = True} _
                                                                , .ItemIds = resItemIDs})
            'declare and fill up the message array that we are going to return
            Dim resItemMessage As ItemType() = Nothing
            For x As Integer = 0 To resGetItem.ResponseMessages.Items.Length - 1
                If IsNothing(resItemMessage) Then ReDim resItemMessage(0) Else ReDim Preserve resItemMessage(resItemMessage.Length)
                resItemMessage(x) = DirectCast(resGetItem.ResponseMessages.Items(x), ItemInfoResponseMessageType).Items.Items(0)
            Next
            'pass back the emails
            Return resItemMessage
        Else
            TraceLog.AppendLine("no unread mail found closing out")
            Return Nothing
        End If
    End If

==========更新============

在 Glen Scales 的正确方向推动下,我们取得了成功! EWS 是类型和派生类型的雷区。

'create the finditemtype and load the restrictions
    'first only the unread messages
    'secondly, only of type "IPM.Note" ie just emails
    Dim reqFindUnreadMailInInbox As FindItemType = New FindItemType With _
    {.Traversal = ItemQueryTraversalType.Shallow _
     , .ItemShape = New ItemResponseShapeType With {.BaseShape = DefaultShapeNamesType.IdOnly} _
     , .ParentFolderIds = New DistinguishedFolderIdType(0) {New DistinguishedFolderIdType With {.Id = DistinguishedFolderIdNameType.inbox}} _
     , .Restriction = New RestrictionType With {.Item = New AndType With { _
    .Items = New IsEqualToType() { _
     New IsEqualToType With {.Item = New PathToUnindexedFieldType With { _
                              .FieldURI = UnindexedFieldURIType.messageIsRead} _
                            , .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "0"}} _
                            } _
     , New IsEqualToType With {.Item = New PathToUnindexedFieldType With { _
                               .FieldURI = UnindexedFieldURIType.itemItemClass} _
                                , .FieldURIOrConstant = New FieldURIOrConstantType With {.Item = New ConstantValueType With {.Value = "IPM.Note"}} _
                                } _
    }}}}

感谢 Glen Scales!

您需要使用 AndType https://msdn.microsoft.com/en-us/library/office/exchangewebservices.andtype(v=exchg.150).aspx

然后定义并添加两个 isEqual 限制,例如

RestrictionType restriction = new RestrictionType();
AndType andType = new AndType();
andType.Items = new SearchExpressionType[] { IsEqual1,IsEqual2 };
restriction.Item = andType;

干杯 格伦