EWS getting phone number from directory folder - exchange-server

I'm querying EWS with DistinguishedFolderId set to Directory. If I add
<t:FieldURI FieldURI="persona:PhoneNumber" />
to the field URIs I don't get the phone number returned. Also if I try to expand the BaseShape to AllProperties I get a failure.
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="persona:DisplayName" />
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="100" Offset="0" BasePoint="Beginning" />
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="directory" />
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
What I'm trying to do is construct a query which will return me the person (not the contact, I need to look into the directory not the contacts) details with the phone number from the tenant.

Ok - found the answer to this one. FindPeople and FindItems aren't going to return the phone number by default, that's some kind of extension.
See here and here where it was partially answered on msdn forums. The solution proposal is to use the GetPersona method and query each PersonId individually.

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 list public folder mailboxes via EWS?

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

Dynamics CRM - Downloading files from notes in C# results in corrupt files with FetchXML

I am using Dynamics CRM and am trying to download a file from the notes (annotation) entity. I am getting the Base64 String and converting to Byte[] like this:
Convert.FromBase64String((string)item.Attributes["documentbody"]);
But when I do so and try to open the file it is corrupt. Word Documents and PDFs refuse to open. Images however open partially. Ie. I get about 3/4 of the image but the rest of the image is solid grey.
I am guessing FetchXML is not returning the full string. Is there a way to to do this in FetchXML, overiding the limit? I have Googled but cannot see any mention of FetchXML limit?
There is a similar SO question here: FetchXml Query Returns Trimmed DocumentBody?
But I am not using "distinct" in my query.
Here is what I have so far:
<fetch>
<entity name="annotation" >
<attribute name="documentbody" />
<filter type="and" >
<condition attribute="objectid" operator="eq" value="{D4FFE0CD-CDFA-E711-80E4-005056BA77B6}" />
<condition attribute="isdocument" operator="eq" value="1" />
</filter>
<order attribute="modifiedon" descending="true" />
</entity>
</fetch>
You don't say how you are saving or opening the file, which I suspect is probably the issue.
Re: "I am guessing FetchXML is not returning the full string" - I don't think that is correct, I've not seen this happen.
This is a working example of saving a file to disk.
Exporting Annotation (Note) Attachment
public void ExportDocuments(IOrganizationService service, String filePath)
{
String fetch = #"<fetch mapping='logical' count='100' version='1.0'>
<entity name='annotation'>
<attribute name='filename' />
<attribute name='documentbody' />
<attribute name='mimetype' />
</entity>
</fetch>";
foreach (Entity e in service.RetrieveMultiple(new FetchExpression(fetch)))
{
if (!String.IsNullOrWhiteSpace(e.Attributes["documentbody"].ToString()))
{
byte[] data = Convert.FromBase64String(e.Attributes["documentbody"].ToString());
File.WriteAllBytes(filePath + e.Attributes["filename"].ToString(), data);
}
}
}
I believe your fetchXML query have the issue. I too faced the same issue but with images in SSRS reports. Images were not loaded properly/got corrupt.
I fixed the issue by updating the fetch XML query with distinct = false as in the below statement.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false" >
.....
</fetch>

Impersonate room in EWS

I am new to Exchange server. I would like to create meeting via EWS. My goal is to book meeting on a room and later pull all the meetings for a specific room. Just knowing the room identifier.
Is it possible to impersonate room in meeting creation or it is just enough to add room as a participant.
A room shouldn't be the organizer of a Meeting so there should be no need to try to impersonate it (by default room accounts are disabled so you can't impersonate a disabled account). The only person you should impersonate is the Organizer of the appointment add the Room as a resource of the Meeting your creating and then send the request to the meeting room mailbox and let Auto-accept handle the rest.
Cheers
Glen
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="
http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://sc
hemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xml
soap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013_SP1" />
<t:TimeZoneContext>
<t:TimeZoneDefinition Name="(UTC+10:00) Canberra, Melbourne, Sydney" Id="AUS Eastern Standard Time">
<t:Periods>
<t:Period Bias="-P0DT11H0M0.0S" Name="Daylight" Id="Dlt/1" />
<t:Period Bias="-P0DT10H0M0.0S" Name="Standard" Id="Std/1" />
<t:Period Bias="-P0DT11H0M0.0S" Name="Daylight" Id="Dlt/2008" />
<t:Period Bias="-P0DT10H0M0.0S" Name="Standard" Id="Std/2008" />
</t:Periods>
<t:TransitionsGroups>
<t:TransitionsGroup Id="0">
<t:RecurringDayTransition>
<t:To Kind="Period">Dlt/1</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>10</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>-1</t:Occurrence>
</t:RecurringDayTransition>
<t:RecurringDayTransition>
<t:To Kind="Period">Std/1</t:To>
<t:TimeOffset>P0DT3H0M0.0S</t:TimeOffset>
<t:Month>3</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>-1</t:Occurrence>
</t:RecurringDayTransition>
</t:TransitionsGroup>
<t:TransitionsGroup Id="1">
<t:RecurringDayTransition>
<t:To Kind="Period">Dlt/2008</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>10</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>1</t:Occurrence>
</t:RecurringDayTransition>
<t:RecurringDayTransition>
<t:To Kind="Period">Std/2008</t:To>
<t:TimeOffset>P0DT3H0M0.0S</t:TimeOffset>
<t:Month>4</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>1</t:Occurrence>
</t:RecurringDayTransition>
</t:TransitionsGroup>
</t:TransitionsGroups>
<t:Transitions>
<t:Transition>
<t:To Kind="Group">0</t:To>
</t:Transition>
<t:AbsoluteDateTransition>
<t:To Kind="Group">1</t:To>
<t:DateTime>2007-12-31T13:00:00.000Z</t:DateTime>
</t:AbsoluteDateTransition>
</t:Transitions>
</t:TimeZoneDefinition>
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem SendMeetingInvitations="SendToAllAndSaveCopy">
<m:Items>
<t:CalendarItem>
<t:Subject>Meeting</t:Subject>
<t:Start>2016-03-01T12:33:17.185+11:00</t:Start>
<t:End>2016-03-01T13:33:17.185+11:00</t:End>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>attendee#mailbox.com</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
<t:Resources>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>room#mailbox.com</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:Resources>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>

Conflict 409 error when creating a Google Shared Contact using API

I'm continually getting a HTTP 409 "Conflict" error when attempting to add a new Google Shared Contact using the API.
I've followed the documentation as closely as possible and have defined the new entry as so:
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<gd:name>
<gd:givenName>Test</gd:givenName>
<gd:familyName>Testerson</gd:familyName>
<gd:fullName>Test Testerson</gd:fullName>
</gd:name>
<atom:content type='text'></atom:content>
<gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='test.testerson#sample.com.au' displayName='' />
<gd:email rel='http://schemas.google.com/g/2005#home' address='' />
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>(07) 33331111</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>0411223344</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#fax'>(07) 33331122</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home'></gd:phoneNumber>
<gd:im address='' protocol='http://schemas.google.com/g/2005#GOOGLE_TALK' primary='true' rel='http://schemas.google.com/g/2005#home' />
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>
<gd:city>Abbey</gd:city>
<gd:street>PO Box 4561</gd:street>
<gd:region>WA</gd:region>
<gd:postcode>6280</gd:postcode>
<gd:country>Australia</gd:country>
<gd:formattedAddress>PO Box 4561, Abbey, WA, 6280, Australia</gd:formattedAddress>
</gd:structuredPostalAddress>
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#other'>
<gd:city>Abbey</gd:city>
<gd:street>47 Example Avenue</gd:street>
<gd:region>WA</gd:region>
<gd:postcode>6280</gd:postcode>
<gd:country>Australia</gd:country>
<gd:formattedAddress>47 Example Avenue, Abbey, WA, 6280, Australia</gd:formattedAddress>
</gd:structuredPostalAddress>
<gd:organization rel='http://schemas.google.com/g/2005#other'>
<gd:orgTitle>Guinea Pig</gd:orgTitle>
<gd:orgName>Test Org</gd:orgName>
</gd:organization>
</atom:entry>
I've set up my HTTP request as follows:
lsToken = GetAuthToken()
Set lobjHttp = CreateObject("MSXML2.XMLHTTP")
Call lobjHttp.Open("POST", CS_FEED_DEFAULT, False, "", "")
Call lobjHttp.setRequestHeader("Authorization", "GoogleLogin auth=" + lsToken)
Call lobjHttp.setRequestHeader("Content-type", "application/atom+xml")
Call lobjHttp.Send(lsOut)
In this example CS_FEED_DEFAULT is the shared contact URL and lsOut is my entry as defined above.
After sending this request I get the 409 response and the following response text:
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
<id>http://www.google.com/m8/feeds/contacts/test.com.au/base/47e904e10dd27dd2</id>
<updated>2014-09-17T02:08:39.761Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>
<title type='text'></title>
<content type='text'></content>
<link rel='http://schemas.google.com/contacts/2008/rel#edit-photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/test.com.au/47e904e10dd27dd2/1B2M2Y8AsgTpgAmY7PhCfg'/>
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/test.com.au/full/47e904e10dd27dd2'/>
<link rel='edit' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/test.com.au/full/47e904e10dd27dd2/1410919719761001'/>
<gd:email rel='http://schemas.google.com/g/2005#work' address='test.testerson#sample.com.au' primary='true'/>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>(07) 33331111</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>0411223344</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work_fax'>(07) 33331122</gd:phoneNumber>
</entry>
Can anyone offer me any advice on this issue?
Thanks.
According to the contacts API documentation, "409 error can be returned when there is a different contact with the same email address. As for now, google contacts API does not allow two different contacts to share an email address".
Have you been trying to add the same email address twice?
I had the same error because I forgot to Start my previously stopped SQL instance on GCP.

Resources