How to list public folder mailboxes via EWS? - outlook

I cannot find any solution to properly list all public folder mailboxes and public folders using SOAP api. I found only powershell commands or C# methods. If anybody know how to get/list all public folders, please provide me with the solution.

To enumerate Public Folders you need to use the FindFolder operation and then make a Shallow traversal query of each folder level starting at the Root (because you can't do deep traversals) eg
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Body>
<FindFolder Traversal="Shallow" xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<FolderShape>
<t:BaseShape>Default</t:BaseShape>
</FolderShape>
<ParentFolderIds>
<t:DistinguishedFolderId Id="publicfoldersroot"/>
</ParentFolderIds>
</FindFolder>
</soap:Body>
</soap:Envelope>
You can't get Public folder Mailboxes using EWS what you should be doing on Office365 is discovering the correct PublicFolder Mailbox to include in the routing headers so you should read through https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-route-public-folder-hierarchy-requests and https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-route-public-folder-content-requests (which both have XML samples for the calls you need).

Firstly, you need to determine the value of the X-AnchorMailbox header using SOAP and make an Autodiscover request to determine the X-PublicFolderInformation value.
Secondly, use FindFolder and then traversal query of each folder level starting at the Root, for example:
<?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="Exchange2013_SP1" />
</soap:Header>
<soap:Body>
<m:FindFolder Traversal="Shallow">
<m:FolderShape>
<t:BaseShape>AllProperties</t:BaseShape>
</m:FolderShape>
<m:IndexedPageFolderView MaxEntriesReturned="1" Offset="0" BasePoint="Beginning" />
<m:Restriction>
<t:IsEqualTo>
<t:FieldURI FieldURI="folder:DisplayName" />
<t:FieldURIOrConstant>
<t:Constant Value="My Public Contacts" />
</t:FieldURIOrConstant>
</t:IsEqualTo>
</m:Restriction>
<m:ParentFolderIds>
<t:FolderId Id="AQEuAAADy/LIWjRCp0GFb0W6aGPbwwEARg5aCLUc8k6wLfl1c0a/2AAAAwIAAAA=" ChangeKey="AQAAABYAAABGDloItRzyTrAt+XVzRr/YAABdo/XB" />
</m:ParentFolderIds>
</m:FindFolder>
</soap:Body>
</soap:Envelope>
Reference from:
Route public folder hierarchy requests
Route public folder content requests

Related

Internal server error with UpdateItem EWS call from Outlook Addin

My goal is to update the subject of an Emailmessage using makeewsrequestasync.
At first I issue a GetItem request to get the latest ChangeKey of the message i want to update. This request works fine and i succesfully get the item ChangeKey.
After that I send another request to finally update my Email subject. However, i always get an internal server error with error code 500. Below is the request i send in the data object of the makeewsrequestasync method.
<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:soap = 'https://schemas.xmlsoap.org/soap/envelope/'> xmlns:t='http://schemas.microsoft.com/exchange/services/2006/types'> <soap:Header> <t:RequestServerVersion Version='Exchange2013'/> </soap:Header> <soap:Body> <UpdateItem MessageDisposition='SaveOnly' ConflictResolution='AutoResolve' xmlns='http://schemas.microsoft.com/exchange/services/2006/messages'> <ItemChanges> <t:ItemChange> <t:ItemId Id='AAMkAGNkZWM1OTUzLTVhMzAtNDQyZS1hYzNmLTFhNDQ5ODc4NTYwMABGAAAAAABB8zSmRPuuRoRPHF1NS2srBwA9GscujNfkQL9s6uP7T+MpAAAAAAEMAADOgKz/bqQyTqxlZnzyc9ndAAH8Uu4tAAA=' ChangeKey='CQAAABYAAADOgKz/bqQyTqxlZnzyc9ndAAILRklX'/> <t:Updates> <t:SetItemField> <t:FieldURI FieldURI='item:Subject'/> <t:Message> <t:Subject>[Venga] MyAnalytics | Network Edition</t:Subject> </t:Message> </t:SetItemField > </t:Updates> </t:ItemChange> </ItemChanges> </UpdateItem> </soap:Body></soap:Envelope>
I already tried several ways to Update my subject, but unfortunetaly without success.
There is a similar question which i used to build my request
(similar Question), but I always end up in the Internal Server Error. I would love to get an advice, how to resolve this issue.
There are multiple issues with your XML request (it's not even valid XML)
<soap:Envelope xmlns:soap = 'https://schemas.xmlsoap.org/soap/envelope/'>
The namespace schema is wrong you have modified the correct schema to https note this has nothing to do with using http or https is just the schema definition and by changing it you have made it invalid. You have also added an extra > at the end which closes the tag but you have extra namespace attributes that should be included in the namespace which just become invalid text at that point in your request eg it should be
<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:t='http://schemas.microsoft.com/exchange/services/2006/types'>
You also have extra whitespace in the closing SetItemField tag. This appears to be valid now
<?xml version='1.0' encoding='utf-8'?>
<soap:Envelope
xmlns:soap = 'http://schemas.xmlsoap.org/soap/envelope/'
xmlns:t='http://schemas.microsoft.com/exchange/services/2006/types'>
<soap:Header>
<t:RequestServerVersion Version='Exchange2013'/>
</soap:Header>
<soap:Body>
<UpdateItem MessageDisposition='SaveOnly' ConflictResolution='AutoResolve'
xmlns='http://schemas.microsoft.com/exchange/services/2006/messages'>
<ItemChanges>
<t:ItemChange>
<t:ItemId Id='AAMkAGNkZWM1OTUzLTVhMzAtNDQyZS1hYzNmLTFhNDQ5ODc4NTYwMABGAAAAAABB8zSmRPuuRoRPHF1NS2srBwA9GscujNfkQL9s6uP7T+MpAAAAAAEMAADOgKz/bqQyTqxlZnzyc9ndAAH8Uu4tAAA=' ChangeKey='CQAAABYAAADOgKz/bqQyTqxlZnzyc9ndAAILRklX'/>
<t:Updates>
<t:SetItemField>
<t:FieldURI FieldURI='item:Subject'/>
<t:Message>
<t:Subject>[Venga] MyAnalytics | Network Edition</t:Subject>
</t:Message>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</ItemChanges>
</UpdateItem>
</soap:Body>
</soap:Envelope>

How to write xpath to checkAddResult value

How to write XPath to get AddResult text value
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AddResponse xmlns="http://tempuri.org/">
<AddResult>128</AddResult>
</AddResponse>
</soap:Body>
</soap:Envelope>
I tried below but not getting the desired result
declare namespace soap='http://www.w3.org/2003/05/soap-envelope';
/soap:Envelope/soap:Body/AddResponse/AddResult/text()
Found Answeer:
I should create another namespace with url same as in response xml and use in xpath,below is the answer
declare namespace soap='http://www.w3.org/2003/05/soap-envelope';
declare namespace xmlns='http://tempuri.org/';
/soap:Envelope/soap:Body/xmlns:AddResponse/xmlns:AddResult/text()

Why does EWS api ErrorNonPrimarySmtpAddress error?

I have several user accounts in Office 365 tenant. Two of them are almost identical (have similar settings but different contact info and name).
I try to fetch information (such as all folders and items) in user's mailbox using GetFolder operation from EWS API that contains next body:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013"/>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>Name.Surname#mydomain.onmicrosoft.com</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<GetFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<FolderShape>
<t:BaseShape>AllProperties</t:BaseShape>
<t:AdditionalProperties> </t:AdditionalProperties>
</FolderShape>
<FolderIds>
<t:DistinguishedFolderId Id="outbox"/>
</FolderIds>
</GetFolder>
</soap:Body>
</soap:Envelope>
I can successfully get info for one of these two mailboxes but when an error reply with the next body:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/exchange/services/2006/types">a:ErrorNonPrimarySmtpAddress</faultcode>
<faultstring xml:lang="en-US">The primary SMTP address must be specified when referencing a mailbox.</faultstring>
<detail>
<e:ResponseCode xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">ErrorNonPrimarySmtpAddress</e:ResponseCode>
<e:Message xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">The primary SMTP address must be specified when referencing a mailbox.</e:Message>
<t:MessageXml xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<t:Value Name="Primary"/>
</t:MessageXml>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
Why do I get such ErrorNonPrimarySmtpAddress error response? What can be the problem when I fetch data in the mailbox of the second user?
You need to use the primary SMTP address - I doubt Name.Surname#mydomain.onmicrosoft.com is the primary address.
Open the address book in Outlook (Ctrl+Shift+B), open the user, switch to the "E-mail Addresses" tab, look for the address with the "SMTP:" prefix (note the caps).

Ruby XML Parsing

I have a sample XML document like
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<SearchSecretsResponse xmlns="urn:thesecretserver.com">
<SearchSecretsResult>
<Errors/>
<SecretSummaries>
<SecretSummary>
<SecretId>86</SecretId>
<SecretName>hostName\root</SecretName>
<SecretTypeName>Unix Root Account (SSH)</SecretTypeName>
</SecretSummary>
</SecretSummaries>
</SearchSecretsResult>
</SearchSecretsResponse>
</soap:Body>
</soap:Envelope>
I am trying to parse it using Nokogiri. My code is
doc = Nokogiri::XML.parse(xml)
puts doc.xpath('//SecretSummary')
But this doesn't print anything. What am I doing wrong ?
You'll need to alias the namespace.
Nokogiri::XML(xml).xpath('//foo:SecretSummary', 'foo' => 'urn:thesecretserver.com')
You could also remove the namespaces
doc.remove_namespaces!

EWS FindItem call returns incorrect EffectiveRights values

I'm using a FindItem call to get items (appointments) from Exchange Web Services (EWS). The properties which are fetched are the item Id and the EffectiveRights. The EffectiveRights property often does not contain the correct values. Sometimes, however, the values are correct (using the same code), but I don't know what causes this.
The Calendar folder I'm searching in is delegated with Author rights to the service user I authenticate with and it contains appointments of which this service user is the author of.
I'm using the ews-java-api library and the response traces show that this isn't a parsing bug.
The code used to retrieve the items:
ItemView view = new ItemView(100);
PropertySet propertySet = new PropertySet();
propertySet.add(ItemSchema.Id);
propertySet.add(ItemSchema.EffectiveRights);
view.setPropertySet(propertySet);
FolderId folderId = new FolderId(WellKnownFolderName.Calendar, Mailbox.getMailboxFromString(targetSmtpAddress));
FindItemsResults<Item> items = service.findItems(folderId, filter, view);
Item firstItem = items.getItems().get(0);
firstItem.getEffectiveRights(); // Returns NONE, READ. This is incorrect.
Item bindItem = Item.bind(service, firstItem.getId()); //
bindItem.getEffectiveRights(); // Returns NONE, READ, MODIFY, DELETE. This is correct.
The request trace:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/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">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010_SP2"></t:RequestServerVersion>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="item:ItemId"></t:FieldURI>
<t:FieldURI FieldURI="item:EffectiveRights"></t:FieldURI>
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="1000" Offset="0" BasePoint="Beginning"></m:IndexedPageItemView>
<m:Restriction>
<t:And>
<t:IsEqualTo>
<t:ExtendedFieldURI PropertySetId="039b4d91-2f03-44da-887c-aad704243ba8" PropertyName="SyncId" PropertyType="String"></t:ExtendedFieldURI>
<t:FieldURIOrConstant>
<t:Constant Value="syncID:330"></t:Constant>
</t:FieldURIOrConstant>
</t:IsEqualTo>
<t:IsGreaterThanOrEqualTo>
<t:FieldURI FieldURI="calendar:Start"></t:FieldURI>
<t:FieldURIOrConstant>
<t:Constant Value="2015-01-28T13:53:38Z"></t:Constant>
</t:FieldURIOrConstant>
</t:IsGreaterThanOrEqualTo>
</t:And>
</m:Restriction>
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="calendar">
<t:Mailbox>
<t:EmailAddress>TARGETUSER#SMTP.ADDRESS</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The trace of a 'faulty' response:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="14" MinorVersion="3" MajorBuildNumber="224" MinorBuildNumber="2" Version="Exchange2010_SP2" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>
</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="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="1000" TotalItemsInView="1868" IncludesLastItemInRange="false">
<t:Items>
<t:CalendarItem>
<t:ItemId Id="AAMkAGVlZmVlY2JjLTcxOTItNDBkYi1hOTljLTkwZjQwZjE4MTU1NQBGAAAAAADZ8IosQv76QbxS0r8FeFzgBwB25IsPmJcKTaP6zvCUqaybAAAAoIe5AAB25IsPmJcKTaP6zvCUqaybAABcSsgnAAA=" ChangeKey="DwAAABYAAAB25IsPmJcKTaP6zvCUqaybAABcS6ER"/>
<t:EffectiveRights>
<t:CreateAssociated>false</t:CreateAssociated>
<t:CreateContents>false</t:CreateContents>
<t:CreateHierarchy>false</t:CreateHierarchy>
<t:Delete>false</t:Delete>
<t:Modify>false</t:Modify>
<t:Read>true</t:Read>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</t:EffectiveRights>
</t:CalendarItem>
<t:CalendarItem>
<t:ItemId Id="AAMkAGVlZmVlY2JjLTcxOTItNDBkYi1hOTljLTkwZjQwZjE4MTU1NQBGAAAAAADZ8IosQv76QbxS0r8FeFzgBwB25IsPmJcKTaP6zvCUqaybAAAAoIe5AAB25IsPmJcKTaP6zvCUqaybAABcSsglAAA=" ChangeKey="DwAAABYAAAB25IsPmJcKTaP6zvCUqaybAABcS6EN"/>
<t:EffectiveRights>
<t:CreateAssociated>false</t:CreateAssociated>
<t:CreateContents>false</t:CreateContents>
<t:CreateHierarchy>false</t:CreateHierarchy>
<t:Delete>false</t:Delete>
<t:Modify>false</t:Modify>
<t:Read>true</t:Read>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</t:EffectiveRights>
</t:CalendarItem>
<!-- MORE ITEMS HERE... -->
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
I already found this blog post which seems somewhat related, but nothing more than that.
FindItems loads values from the contents table of a folder, rather than from the items themselves. Many times, with computed properties like EffectiveRights, a simplistic approach is used to populate the table to give an approximation. It seems like that's what's happening here. The comment in your code mentions that the value is correct after you Bind to the item (which loads values from the item itself).

Resources